WIP commit, (just in case my HD breaks down). Don't expect anything to work. Code crashes and sim doesn't work ;)
This commit is contained in:
@@ -122,7 +122,7 @@ void cloth_free_modifier ( ClothModifierData *clmd );
|
||||
void implicit_set_positions ( ClothModifierData *clmd );
|
||||
|
||||
// from cloth.c, needed for modifier.c
|
||||
void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts );
|
||||
DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
@@ -132,9 +132,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, fl
|
||||
////////////////////////////////////////////////
|
||||
void cloth_free_modifier ( ClothModifierData *clmd );
|
||||
void cloth_init ( ClothModifierData *clmd );
|
||||
void cloth_deform_verts ( struct Object *ob, float framenr, float ( *vertexCos ) [3], int numVerts, void *derivedData, ClothModifierData *clmd );
|
||||
void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface );
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
@@ -44,21 +44,21 @@
|
||||
#include "BKE_DerivedMesh.h"
|
||||
|
||||
// used in kdop.c and collision.c
|
||||
typedef struct Tree
|
||||
typedef struct CollisionTree
|
||||
{
|
||||
struct Tree *nodes[4]; // 4 children --> quad-tree
|
||||
struct Tree *parent;
|
||||
struct Tree *nextLeaf;
|
||||
struct Tree *prevLeaf;
|
||||
struct CollisionTree *nodes[4]; // 4 children --> quad-tree
|
||||
struct CollisionTree *parent;
|
||||
struct CollisionTree *nextLeaf;
|
||||
struct CollisionTree *prevLeaf;
|
||||
float bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP
|
||||
unsigned int tri_index; // this saves the index of the face
|
||||
int point_index[4]; // supports up to 4 points in a leaf
|
||||
int count_nodes; // how many nodes are used
|
||||
int traversed; // how many nodes already traversed until this level?
|
||||
int isleaf;
|
||||
}
|
||||
Tree;
|
||||
CollisionTree;
|
||||
|
||||
typedef struct Tree TreeNode;
|
||||
typedef struct CollisionTree TreeNode;
|
||||
|
||||
typedef struct BVH
|
||||
{
|
||||
@@ -79,7 +79,7 @@ BVH;
|
||||
/* used for collisions in kdop.c and also collision.c*/
|
||||
typedef struct CollisionPair
|
||||
{
|
||||
unsigned int indexA, indexB;
|
||||
int point_indexA[4], point_indexB[4];
|
||||
}
|
||||
CollisionPair;
|
||||
|
||||
@@ -89,18 +89,21 @@ CollisionPair;
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
// builds bounding volume hierarchy
|
||||
BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xold, unsigned int numverts, float epsilon);
|
||||
BVH *bvh_build (MFace *mfaces, unsigned int numfaces, MVert *x, MVert *xnew, unsigned int numverts, float epsilon);
|
||||
// frees the same
|
||||
void bvh_free ( BVH *bvh );
|
||||
|
||||
// checks two bounding volume hierarchies for potential collisions and returns some list with those
|
||||
int bvh_traverse(Tree *tree1, Tree *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(DerivedMesh *dm, BVH * bvh, int moving);
|
||||
void bvh_update(BVH * bvh, int moving);
|
||||
|
||||
LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr );
|
||||
LinkNode *BLI_linklist_append_fast (LinkNode **listp, void *ptr);
|
||||
|
||||
// move Collision modifier object inter-frame with step = [0,1]
|
||||
// defined in collisions.c
|
||||
void collision_move_object(CollisionModifierData *collmd, float step);
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -277,7 +277,7 @@ int modifiers_getCageIndex(struct Object *ob,
|
||||
int *lastPossibleCageIndex_r);
|
||||
|
||||
int modifiers_isSoftbodyEnabled(struct Object *ob);
|
||||
struct ModifierData *modifiers_isClothEnabled(struct Object *ob);
|
||||
struct ClothModifierData *modifiers_isClothEnabled(Object *ob);
|
||||
struct Object *modifiers_isDeformedByArmature(struct Object *ob);
|
||||
struct Object *modifiers_isDeformedByLattice(struct Object *ob);
|
||||
int modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
|
||||
|
||||
@@ -120,10 +120,9 @@ static CM_SOLVER_DEF solvers [] =
|
||||
/* ********** cloth engine ******* */
|
||||
/* Prototypes for internal functions.
|
||||
*/
|
||||
static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts );
|
||||
static void cloth_to_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
|
||||
static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
|
||||
static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts );
|
||||
static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts );
|
||||
static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
|
||||
int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm );
|
||||
static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short vgroup );
|
||||
|
||||
@@ -603,69 +602,63 @@ void cloth_cache_free ( ClothModifierData *clmd, float time )
|
||||
* cloth_deform_verts - simulates one step, framenr is in frames.
|
||||
*
|
||||
**/
|
||||
void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
|
||||
float ( *vertexCos ) [3], int numverts )
|
||||
DerivedMesh *clothModifier_do(ClothModifierData *clmd,
|
||||
Object *ob, DerivedMesh *dm)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int numedges = -1;
|
||||
unsigned int numfaces = -1;
|
||||
MVert *mvert = NULL;
|
||||
MEdge *medge = NULL;
|
||||
MFace *mface = NULL;
|
||||
DerivedMesh *result = NULL, *result2 = NULL;
|
||||
DerivedMesh *result = NULL;
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
unsigned int framenr = ( float ) G.scene->r.cfra;
|
||||
float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
|
||||
ListBase *effectors = NULL;
|
||||
ClothVertex *newframe= NULL, *verts;
|
||||
ListBase *effectors = NULL;
|
||||
ClothVertex *verts = NULL;
|
||||
Frame *frame = NULL;
|
||||
LinkNode *search = NULL;
|
||||
float deltaTime = current_time - clmd->sim_parms.sim_time;
|
||||
MVert *mverts = NULL;
|
||||
|
||||
result = CDDM_copy(dm);
|
||||
|
||||
// only be active during a specific period:
|
||||
// that's "first frame" and "last frame" on GUI
|
||||
if ( ! ( clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) )
|
||||
if ( clmd->clothObject )
|
||||
{
|
||||
if ( clmd->clothObject )
|
||||
if ( clmd->sim_parms.cache )
|
||||
{
|
||||
if ( clmd->sim_parms.cache )
|
||||
if ( current_time < clmd->sim_parms.firstframe )
|
||||
{
|
||||
if ( current_time < clmd->sim_parms.firstframe )
|
||||
int frametime = cloth_cache_first_frame ( clmd );
|
||||
if ( cloth_cache_search_frame ( clmd, frametime ) )
|
||||
{
|
||||
int frametime = cloth_cache_first_frame ( clmd );
|
||||
if ( cloth_cache_search_frame ( clmd, frametime ) )
|
||||
{
|
||||
cloth_cache_get_frame ( clmd, frametime );
|
||||
cloth_to_object ( ob, clmd, vertexCos, numverts );
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ( current_time > clmd->sim_parms.lastframe )
|
||||
{
|
||||
int frametime = cloth_cache_last_frame ( clmd );
|
||||
if ( cloth_cache_search_frame ( clmd, frametime ) )
|
||||
{
|
||||
cloth_cache_get_frame ( clmd, frametime );
|
||||
cloth_to_object ( ob, clmd, vertexCos, numverts );
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed
|
||||
{
|
||||
if ( cloth_cache_search_frame ( clmd, framenr ) )
|
||||
{
|
||||
cloth_cache_get_frame ( clmd, framenr );
|
||||
cloth_to_object ( ob, clmd, vertexCos, numverts );
|
||||
}
|
||||
clmd->sim_parms.sim_time = current_time;
|
||||
return;
|
||||
cloth_cache_get_frame ( clmd, frametime );
|
||||
cloth_to_object ( ob, clmd, result );
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ( current_time > clmd->sim_parms.lastframe )
|
||||
{
|
||||
int frametime = cloth_cache_last_frame ( clmd );
|
||||
if ( cloth_cache_search_frame ( clmd, frametime ) )
|
||||
{
|
||||
cloth_cache_get_frame ( clmd, frametime );
|
||||
cloth_to_object ( ob, clmd, result );
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed
|
||||
{
|
||||
if ( cloth_cache_search_frame ( clmd, framenr ) )
|
||||
{
|
||||
cloth_cache_get_frame ( clmd, framenr );
|
||||
cloth_to_object ( ob, clmd, result );
|
||||
}
|
||||
clmd->sim_parms.sim_time = current_time;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// unused in the moment, calculated seperately in implicit.c
|
||||
clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame;
|
||||
|
||||
@@ -673,9 +666,9 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
|
||||
|
||||
if ( deltaTime == 1.0f )
|
||||
{
|
||||
if ( ( clmd->clothObject == NULL ) || ( numverts != clmd->clothObject->numverts ) )
|
||||
if ( ( clmd->clothObject == NULL ) || ( dm->getNumVerts(dm) != clmd->clothObject->numverts ) )
|
||||
{
|
||||
if ( !cloth_from_object ( ob, clmd, dm, vertexCos, numverts ) )
|
||||
if ( !cloth_from_object ( ob, clmd, dm ) )
|
||||
return;
|
||||
|
||||
if ( clmd->clothObject == NULL )
|
||||
@@ -692,6 +685,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
|
||||
if ( !cloth_cache_search_frame ( clmd, framenr ) )
|
||||
{
|
||||
verts = cloth->verts;
|
||||
mverts = dm->getVertArray(dm);
|
||||
|
||||
// Force any pinned verts to their constrained location.
|
||||
for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ )
|
||||
@@ -699,9 +693,8 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
|
||||
// Save the previous position.
|
||||
VECCOPY ( verts->xold, verts->xconst );
|
||||
VECCOPY ( verts->txold, verts->x );
|
||||
|
||||
// Get the current position.
|
||||
VECCOPY ( verts->xconst, vertexCos[i] );
|
||||
VECCOPY ( verts->xconst, mverts[i].co );
|
||||
Mat4MulVecfl ( ob->obmat, verts->xconst );
|
||||
}
|
||||
|
||||
@@ -723,7 +716,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
|
||||
}
|
||||
|
||||
// Copy the result back to the object.
|
||||
cloth_to_object ( ob, clmd, vertexCos, numverts );
|
||||
cloth_to_object ( ob, clmd, result );
|
||||
|
||||
// bvh_free(clmd->clothObject->tree);
|
||||
// clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon);
|
||||
@@ -737,11 +730,12 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
|
||||
if ( cloth_cache_search_frame ( clmd, framenr ) )
|
||||
{
|
||||
cloth_cache_get_frame ( clmd, framenr );
|
||||
cloth_to_object ( ob, clmd, vertexCos, numverts );
|
||||
cloth_to_object ( ob, clmd, result );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* frees all */
|
||||
@@ -771,6 +765,14 @@ void cloth_free_modifier ( ClothModifierData *clmd )
|
||||
// Free the verts.
|
||||
if ( cloth->verts != NULL )
|
||||
MEM_freeN ( cloth->verts );
|
||||
|
||||
// Free the verts.
|
||||
if ( cloth->x != NULL )
|
||||
MEM_freeN ( cloth->x );
|
||||
|
||||
// Free the verts.
|
||||
if ( cloth->xnew != NULL )
|
||||
MEM_freeN ( cloth->xnew );
|
||||
|
||||
cloth->verts = NULL;
|
||||
cloth->numverts = 0;
|
||||
@@ -823,22 +825,24 @@ void cloth_free_modifier ( ClothModifierData *clmd )
|
||||
*
|
||||
* This function is a modified version of the softbody.c:softbody_to_object() function.
|
||||
**/
|
||||
static void cloth_to_object ( Object *ob, ClothModifierData *clmd, float ( *vertexCos ) [3], unsigned int numverts )
|
||||
static void cloth_to_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm )
|
||||
{
|
||||
ClothVertex *verts = NULL;
|
||||
unsigned int i = 0;
|
||||
MVert *mvert = NULL;
|
||||
|
||||
if ( clmd->clothObject )
|
||||
{
|
||||
verts = clmd->clothObject->verts;
|
||||
mvert = dm->getVertArray(dm);
|
||||
|
||||
/* inverse matrix is not uptodate... */
|
||||
Mat4Invert ( ob->imat, ob->obmat );
|
||||
|
||||
for ( i = 0; i < numverts; i++, verts++ )
|
||||
for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ )
|
||||
{
|
||||
VECCOPY ( vertexCos[i], verts->x );
|
||||
Mat4MulVecfl ( ob->imat, vertexCos[i] ); /* softbody is in global coords */
|
||||
VECCOPY ( mvert[i].co, verts->x );
|
||||
Mat4MulVecfl ( ob->imat, mvert[i].co ); /* softbody is in global coords */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -903,7 +907,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short
|
||||
}
|
||||
|
||||
// only meshes supported at the moment
|
||||
static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float ( *vertexCos ) [3], unsigned int numverts )
|
||||
static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm )
|
||||
{
|
||||
unsigned int i = 0;
|
||||
// dm->getNumVerts(dm);
|
||||
@@ -954,7 +958,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh
|
||||
verts = clmd->clothObject->verts;
|
||||
|
||||
/* set initial values */
|
||||
for ( i = 0; i < numverts; i++, verts++ )
|
||||
for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ )
|
||||
{
|
||||
VECCOPY ( verts->x, mvert[i].co );
|
||||
Mat4MulVecfl ( ob->obmat, verts->x );
|
||||
@@ -1021,6 +1025,22 @@ static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *
|
||||
modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." );
|
||||
return;
|
||||
}
|
||||
|
||||
clmd->clothObject->x = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_x" );
|
||||
if ( clmd->clothObject->x == NULL )
|
||||
{
|
||||
cloth_free_modifier ( clmd );
|
||||
modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->x." );
|
||||
return;
|
||||
}
|
||||
|
||||
clmd->clothObject->xnew = MEM_callocN ( sizeof ( MVert ) * clmd->clothObject->numverts, "Cloth MVert_xnew" );
|
||||
if ( clmd->clothObject->xnew == NULL )
|
||||
{
|
||||
cloth_free_modifier ( clmd );
|
||||
modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xnew." );
|
||||
return;
|
||||
}
|
||||
|
||||
// save face information
|
||||
clmd->clothObject->numfaces = numfaces;
|
||||
@@ -1067,7 +1087,10 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in
|
||||
cloth->numsprings++;
|
||||
|
||||
BLI_linklist_append ( &cloth->springs, spring );
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm )
|
||||
|
||||
@@ -72,6 +72,22 @@
|
||||
#include "Bullet-C-Api.h"
|
||||
|
||||
|
||||
// step is limited from 0 (frame start position) to 1 (frame end position)
|
||||
void collision_move_object(CollisionModifierData *collmd, float step)
|
||||
{
|
||||
float tv[3] = {0,0,0};
|
||||
unsigned int i = 0;
|
||||
MVert *tempVert = collmd->current_x;
|
||||
collmd->current_x = collmd->current_xnew;
|
||||
collmd->current_xnew = tempVert;
|
||||
|
||||
for ( i = 0; i < collmd->numverts; i++ )
|
||||
{
|
||||
VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co);
|
||||
VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gsl_poly_solve_cubic -
|
||||
@@ -362,846 +378,3 @@ DO_INLINE void interpolateOnTriangle(float to[3], float v1[3], float v2[3], floa
|
||||
VECADDMUL(to, v3, w3);
|
||||
}
|
||||
|
||||
// unused in the moment, has some bug in
|
||||
DO_INLINE void calculateFrictionImpulse(float to[3], float vrel[3], float normal[3], double normalVelocity,
|
||||
double frictionConstant, double delta_V_n)
|
||||
{
|
||||
float vrel_t_pre[3];
|
||||
float vrel_t[3];
|
||||
VECSUBS(vrel_t_pre, vrel, normal, normalVelocity);
|
||||
VECCOPY(to, vrel_t_pre);
|
||||
VecMulf(to, MAX2(1.0f - frictionConstant * delta_V_n / INPR(vrel_t_pre,vrel_t_pre), 0.0f));
|
||||
}
|
||||
|
||||
int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd)
|
||||
{
|
||||
/*
|
||||
unsigned int i = 0;
|
||||
int result = 0;
|
||||
LinkNode *search = NULL;
|
||||
CollPair *collpair = NULL;
|
||||
Cloth *cloth1, *cloth2;
|
||||
float w1, w2, w3, u1, u2, u3;
|
||||
float v1[3], v2[3], relativeVelocity[3];
|
||||
float magrelVel;
|
||||
|
||||
cloth1 = clmd->clothObject;
|
||||
cloth2 = coll_clmd->clothObject;
|
||||
|
||||
// search = clmd->coll_parms.collision_list;
|
||||
|
||||
while(search)
|
||||
{
|
||||
collpair = search->link;
|
||||
|
||||
// compute barycentric coordinates for both collision points
|
||||
collisions_compute_barycentric(collpair->pa,
|
||||
cloth1->verts[collpair->ap1].txold,
|
||||
cloth1->verts[collpair->ap2].txold,
|
||||
cloth1->verts[collpair->ap3].txold,
|
||||
&w1, &w2, &w3);
|
||||
|
||||
collisions_compute_barycentric(collpair->pb,
|
||||
cloth2->verts[collpair->bp1].txold,
|
||||
cloth2->verts[collpair->bp2].txold,
|
||||
cloth2->verts[collpair->bp3].txold,
|
||||
&u1, &u2, &u3);
|
||||
|
||||
// Calculate relative "velocity".
|
||||
interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3);
|
||||
|
||||
interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3);
|
||||
|
||||
VECSUB(relativeVelocity, v1, v2);
|
||||
|
||||
// Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
|
||||
magrelVel = INPR(relativeVelocity, collpair->normal);
|
||||
|
||||
// printf("magrelVel: %f\n", magrelVel);
|
||||
|
||||
// Calculate masses of points.
|
||||
|
||||
// If v_n_mag < 0 the edges are approaching each other.
|
||||
if(magrelVel < -ALMOST_ZERO)
|
||||
{
|
||||
// Calculate Impulse magnitude to stop all motion in normal direction.
|
||||
// const double I_mag = v_n_mag / (1/m1 + 1/m2);
|
||||
float magnitude_i = magrelVel / 2.0f; // TODO implement masses
|
||||
float tangential[3], magtangent, magnormal, collvel[3];
|
||||
float vrel_t_pre[3];
|
||||
float vrel_t[3];
|
||||
double impulse;
|
||||
float epsilon = clmd->coll_parms.epsilon;
|
||||
float overlap = (epsilon + ALMOST_ZERO-collpair->distance);
|
||||
|
||||
// calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel);
|
||||
|
||||
// magtangent = INPR(tangential, tangential);
|
||||
|
||||
// Apply friction impulse.
|
||||
if (magtangent < -ALMOST_ZERO)
|
||||
{
|
||||
|
||||
// printf("friction applied: %f\n", magtangent);
|
||||
// TODO check original code
|
||||
}
|
||||
|
||||
|
||||
impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
|
||||
|
||||
// printf("impulse: %f\n", impulse);
|
||||
|
||||
// face A
|
||||
VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse);
|
||||
cloth1->verts[collpair->ap1].impulse_count++;
|
||||
|
||||
VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse);
|
||||
cloth1->verts[collpair->ap2].impulse_count++;
|
||||
|
||||
VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse);
|
||||
cloth1->verts[collpair->ap3].impulse_count++;
|
||||
|
||||
// face B
|
||||
VECADDMUL(cloth2->verts[collpair->bp1].impulse, collpair->normal, u1 * impulse);
|
||||
cloth2->verts[collpair->bp1].impulse_count++;
|
||||
|
||||
VECADDMUL(cloth2->verts[collpair->bp2].impulse, collpair->normal, u2 * impulse);
|
||||
cloth2->verts[collpair->bp2].impulse_count++;
|
||||
|
||||
VECADDMUL(cloth2->verts[collpair->bp3].impulse, collpair->normal, u3 * impulse);
|
||||
cloth2->verts[collpair->bp3].impulse_count++;
|
||||
|
||||
|
||||
result = 1;
|
||||
|
||||
// printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case
|
||||
|
||||
// Apply the impulse and increase impulse counters.
|
||||
|
||||
|
||||
}
|
||||
|
||||
search = search->next;
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int collisions_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int collisions_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
|
||||
{
|
||||
/*
|
||||
CollPair *collpair = NULL;
|
||||
Cloth *cloth1=NULL, *cloth2=NULL;
|
||||
MFace *face1=NULL, *face2=NULL;
|
||||
ClothVertex *verts1=NULL, *verts2=NULL;
|
||||
double distance = 0;
|
||||
float epsilon = clmd->coll_parms.epsilon;
|
||||
unsigned int i = 0;
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair");
|
||||
|
||||
cloth1 = clmd->clothObject;
|
||||
cloth2 = coll_clmd->clothObject;
|
||||
|
||||
verts1 = cloth1->verts;
|
||||
verts2 = cloth2->verts;
|
||||
|
||||
face1 = &(cloth1->mfaces[tree1->tri_index]);
|
||||
face2 = &(cloth2->mfaces[tree2->tri_index]);
|
||||
|
||||
// check all possible pairs of triangles
|
||||
if(i == 0)
|
||||
{
|
||||
collpair->ap1 = face1->v1;
|
||||
collpair->ap2 = face1->v2;
|
||||
collpair->ap3 = face1->v3;
|
||||
|
||||
collpair->bp1 = face2->v1;
|
||||
collpair->bp2 = face2->v2;
|
||||
collpair->bp3 = face2->v3;
|
||||
|
||||
}
|
||||
|
||||
if(i == 1)
|
||||
{
|
||||
if(face1->v4)
|
||||
{
|
||||
collpair->ap1 = face1->v3;
|
||||
collpair->ap2 = face1->v4;
|
||||
collpair->ap3 = face1->v1;
|
||||
|
||||
collpair->bp1 = face2->v1;
|
||||
collpair->bp2 = face2->v2;
|
||||
collpair->bp3 = face2->v3;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
if(i == 2)
|
||||
{
|
||||
if(face2->v4)
|
||||
{
|
||||
collpair->ap1 = face1->v1;
|
||||
collpair->ap2 = face1->v2;
|
||||
collpair->ap3 = face1->v3;
|
||||
|
||||
collpair->bp1 = face2->v3;
|
||||
collpair->bp2 = face2->v4;
|
||||
collpair->bp3 = face2->v1;
|
||||
}
|
||||
else
|
||||
i+=2;
|
||||
}
|
||||
|
||||
if(i == 3)
|
||||
{
|
||||
if((face1->v4)&&(face2->v4))
|
||||
{
|
||||
collpair->ap1 = face1->v3;
|
||||
collpair->ap2 = face1->v4;
|
||||
collpair->ap3 = face1->v1;
|
||||
|
||||
collpair->bp1 = face2->v3;
|
||||
collpair->bp2 = face2->v4;
|
||||
collpair->bp3 = face2->v1;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
// calc SIPcode (?)
|
||||
|
||||
if(i < 4)
|
||||
{
|
||||
// calc distance + normal
|
||||
distance = plNearestPoints(
|
||||
verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector);
|
||||
|
||||
if (distance <= (epsilon + ALMOST_ZERO))
|
||||
{
|
||||
// printf("dist: %f\n", (float)distance);
|
||||
|
||||
// collpair->face1 = tree1->tri_index;
|
||||
// collpair->face2 = tree2->tri_index;
|
||||
|
||||
// VECCOPY(collpair->normal, collpair->vector);
|
||||
// Normalize(collpair->normal);
|
||||
|
||||
// collpair->distance = distance;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
MEM_freeN(collpair);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MEM_freeN(collpair);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair)
|
||||
{
|
||||
Cloth *cloth1, *cloth2;
|
||||
ClothVertex *verts1, *verts2;
|
||||
float temp[3];
|
||||
|
||||
cloth1 = clmd->clothObject;
|
||||
cloth2 = coll_clmd->clothObject;
|
||||
|
||||
verts1 = cloth1->verts;
|
||||
verts2 = cloth2->verts;
|
||||
|
||||
VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold);
|
||||
if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
|
||||
return 1;
|
||||
|
||||
VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold);
|
||||
if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
|
||||
return 1;
|
||||
|
||||
VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold);
|
||||
if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
|
||||
return 1;
|
||||
|
||||
VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold);
|
||||
if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void collisions_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
|
||||
{
|
||||
EdgeCollPair edgecollpair;
|
||||
Cloth *cloth1=NULL, *cloth2=NULL;
|
||||
MFace *face1=NULL, *face2=NULL;
|
||||
ClothVertex *verts1=NULL, *verts2=NULL;
|
||||
double distance = 0;
|
||||
float epsilon = clmd->coll_parms.epsilon;
|
||||
unsigned int i = 0, j = 0, k = 0;
|
||||
int numsolutions = 0;
|
||||
float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
|
||||
|
||||
cloth1 = clmd->clothObject;
|
||||
cloth2 = coll_clmd->clothObject;
|
||||
|
||||
verts1 = cloth1->verts;
|
||||
verts2 = cloth2->verts;
|
||||
|
||||
face1 = &(cloth1->mfaces[tree1->tri_index]);
|
||||
face2 = &(cloth2->mfaces[tree2->tri_index]);
|
||||
|
||||
for( i = 0; i < 5; i++)
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
edgecollpair.p11 = face1->v1;
|
||||
edgecollpair.p12 = face1->v2;
|
||||
}
|
||||
else if(i == 1)
|
||||
{
|
||||
edgecollpair.p11 = face1->v2;
|
||||
edgecollpair.p12 = face1->v3;
|
||||
}
|
||||
else if(i == 2)
|
||||
{
|
||||
if(face1->v4)
|
||||
{
|
||||
edgecollpair.p11 = face1->v3;
|
||||
edgecollpair.p12 = face1->v4;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgecollpair.p11 = face1->v3;
|
||||
edgecollpair.p12 = face1->v1;
|
||||
i+=5; // get out of here after this edge pair is handled
|
||||
}
|
||||
}
|
||||
else if(i == 3)
|
||||
{
|
||||
if(face1->v4)
|
||||
{
|
||||
edgecollpair.p11 = face1->v4;
|
||||
edgecollpair.p12 = face1->v1;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgecollpair.p11 = face1->v3;
|
||||
edgecollpair.p12 = face1->v1;
|
||||
}
|
||||
|
||||
|
||||
for( j = 0; j < 5; j++)
|
||||
{
|
||||
if(j == 0)
|
||||
{
|
||||
edgecollpair.p21 = face2->v1;
|
||||
edgecollpair.p22 = face2->v2;
|
||||
}
|
||||
else if(j == 1)
|
||||
{
|
||||
edgecollpair.p21 = face2->v2;
|
||||
edgecollpair.p22 = face2->v3;
|
||||
}
|
||||
else if(j == 2)
|
||||
{
|
||||
if(face2->v4)
|
||||
{
|
||||
edgecollpair.p21 = face2->v3;
|
||||
edgecollpair.p22 = face2->v4;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgecollpair.p21 = face2->v3;
|
||||
edgecollpair.p22 = face2->v1;
|
||||
}
|
||||
}
|
||||
else if(j == 3)
|
||||
{
|
||||
if(face2->v4)
|
||||
{
|
||||
edgecollpair.p21 = face2->v4;
|
||||
edgecollpair.p22 = face2->v1;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgecollpair.p21 = face2->v3;
|
||||
edgecollpair.p22 = face2->v1;
|
||||
}
|
||||
|
||||
|
||||
if(!collisions_are_edges_adjacent(clmd, coll_clmd, &edgecollpair))
|
||||
{
|
||||
VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold);
|
||||
VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v);
|
||||
VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold);
|
||||
VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v);
|
||||
VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold);
|
||||
VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v);
|
||||
|
||||
numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
|
||||
|
||||
for (k = 0; k < numsolutions; k++)
|
||||
{
|
||||
if ((solution[k] >= 0.0) && (solution[k] <= 1.0))
|
||||
{
|
||||
float out_collisionTime = solution[k];
|
||||
|
||||
// TODO: check for collisions
|
||||
|
||||
// TODO: put into (edge) collision list
|
||||
|
||||
printf("Moving edge found!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void collisions_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
|
||||
{
|
||||
/*
|
||||
CollPair collpair;
|
||||
Cloth *cloth1=NULL, *cloth2=NULL;
|
||||
MFace *face1=NULL, *face2=NULL;
|
||||
ClothVertex *verts1=NULL, *verts2=NULL;
|
||||
double distance = 0;
|
||||
float epsilon = clmd->coll_parms.epsilon;
|
||||
unsigned int i = 0, j = 0, k = 0;
|
||||
int numsolutions = 0;
|
||||
float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
|
||||
|
||||
for(i = 0; i < 2; i++)
|
||||
{
|
||||
cloth1 = clmd->clothObject;
|
||||
cloth2 = coll_clmd->clothObject;
|
||||
|
||||
verts1 = cloth1->verts;
|
||||
verts2 = cloth2->verts;
|
||||
|
||||
face1 = &(cloth1->mfaces[tree1->tri_index]);
|
||||
face2 = &(cloth2->mfaces[tree2->tri_index]);
|
||||
|
||||
// check all possible pairs of triangles
|
||||
if(i == 0)
|
||||
{
|
||||
collpair.ap1 = face1->v1;
|
||||
collpair.ap2 = face1->v2;
|
||||
collpair.ap3 = face1->v3;
|
||||
|
||||
collpair.pointsb[0] = face2->v1;
|
||||
collpair.pointsb[1] = face2->v2;
|
||||
collpair.pointsb[2] = face2->v3;
|
||||
collpair.pointsb[3] = face2->v4;
|
||||
}
|
||||
|
||||
if(i == 1)
|
||||
{
|
||||
if(face1->v4)
|
||||
{
|
||||
collpair.ap1 = face1->v3;
|
||||
collpair.ap2 = face1->v4;
|
||||
collpair.ap3 = face1->v1;
|
||||
|
||||
collpair.pointsb[0] = face2->v1;
|
||||
collpair.pointsb[1] = face2->v2;
|
||||
collpair.pointsb[2] = face2->v3;
|
||||
collpair.pointsb[3] = face2->v4;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
// calc SIPcode (?)
|
||||
|
||||
if(i < 2)
|
||||
{
|
||||
VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold);
|
||||
VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v);
|
||||
VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold);
|
||||
VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v);
|
||||
|
||||
for(j = 0; j < 4; j++)
|
||||
{
|
||||
if((j==3) && !(face2->v4))
|
||||
break;
|
||||
|
||||
VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold);
|
||||
VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v);
|
||||
|
||||
numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
|
||||
|
||||
for (k = 0; k < numsolutions; k++)
|
||||
{
|
||||
if ((solution[k] >= 0.0) && (solution[k] <= 1.0))
|
||||
{
|
||||
float out_collisionTime = solution[k];
|
||||
|
||||
// TODO: check for collisions
|
||||
|
||||
// TODO: put into (point-face) collision list
|
||||
|
||||
printf("Moving found!\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check borders for collisions
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
|
||||
{
|
||||
/*
|
||||
// TODO: check for adjacent
|
||||
collisions_collision_moving_edges(clmd, coll_clmd, tree1, tree2);
|
||||
|
||||
collisions_collision_moving_tris(clmd, coll_clmd, tree1, tree2);
|
||||
collisions_collision_moving_tris(coll_clmd, clmd, tree2, tree1);
|
||||
*/
|
||||
}
|
||||
|
||||
// move collision objects forward in time and update static bounding boxes
|
||||
void collisions_update_collision_objects(float step)
|
||||
{
|
||||
Base *base=NULL;
|
||||
ClothModifierData *coll_clmd=NULL;
|
||||
Object *coll_ob=NULL;
|
||||
unsigned int i=0;
|
||||
|
||||
// search all objects for collision object
|
||||
for (base = G.scene->base.first; base; base = base->next)
|
||||
{
|
||||
|
||||
coll_ob = base->object;
|
||||
coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
|
||||
if (!coll_clmd)
|
||||
continue;
|
||||
|
||||
// if collision object go on
|
||||
if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
|
||||
{
|
||||
if (coll_clmd->clothObject && coll_clmd->clothObject->tree)
|
||||
{
|
||||
Cloth *coll_cloth = coll_clmd->clothObject;
|
||||
BVH *coll_bvh = coll_clmd->clothObject->tree;
|
||||
unsigned int coll_numverts = coll_cloth->numverts;
|
||||
|
||||
// update position of collision object
|
||||
for(i = 0; i < coll_numverts; i++)
|
||||
{
|
||||
VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx);
|
||||
|
||||
VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step);
|
||||
|
||||
// no dt here because of float rounding errors
|
||||
VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold);
|
||||
}
|
||||
|
||||
// update BVH of collision object
|
||||
// bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING
|
||||
}
|
||||
else
|
||||
printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// collisions_MAX_THRESHOLD defines how much collision rounds/loops should be taken
|
||||
#define CLOTH_MAX_THRESHOLD 10
|
||||
|
||||
// cloth - object collisions
|
||||
int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
|
||||
{
|
||||
Base *base=NULL;
|
||||
ClothModifierData *coll_clmd=NULL;
|
||||
Cloth *cloth=NULL;
|
||||
Object *coll_ob=NULL;
|
||||
BVH *collisions_bvh=NULL;
|
||||
unsigned int 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;
|
||||
LinkNode *collision_list = NULL;
|
||||
|
||||
if ((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cloth = clmd->clothObject;
|
||||
verts = cloth->verts;
|
||||
collisions_bvh = (BVH *) cloth->tree;
|
||||
numfaces = clmd->clothObject->numfaces;
|
||||
numverts = clmd->clothObject->numverts;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// static collisions
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// update cloth bvh
|
||||
// bvh_update(clmd, collisions_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
|
||||
|
||||
// update collision objects
|
||||
collisions_update_collision_objects(step);
|
||||
|
||||
do
|
||||
{
|
||||
result = 0;
|
||||
ic = 0;
|
||||
|
||||
// check all collision objects
|
||||
for (base = G.scene->base.first; base; base = base->next)
|
||||
{
|
||||
coll_ob = base->object;
|
||||
coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
|
||||
|
||||
if (!coll_clmd)
|
||||
continue;
|
||||
|
||||
// if collision object go on
|
||||
if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
|
||||
{
|
||||
if (coll_clmd->clothObject && coll_clmd->clothObject->tree)
|
||||
{
|
||||
BVH *coll_bvh = coll_clmd->clothObject->tree;
|
||||
|
||||
// fill collision list
|
||||
bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list);
|
||||
|
||||
// process all collisions (calculate impulses, TODO: also repulses if distance too short)
|
||||
result = 1;
|
||||
for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence
|
||||
{
|
||||
result = 0;
|
||||
|
||||
// result += collisions_collision_response_static_tris(clmd, coll_clmd, collision_list, 0);
|
||||
|
||||
// result += collisions_collision_response_static_tris(coll_clmd, clmd, collision_list, 1);
|
||||
|
||||
// apply impulses in parallel
|
||||
ic=0;
|
||||
for(i = 0; i < numverts; 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);
|
||||
VECCOPY(verts[i].impulse, tnull);
|
||||
verts[i].impulse_count = 0;
|
||||
|
||||
ic++;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// free collision list
|
||||
if(collision_list)
|
||||
{
|
||||
LinkNode *search = collision_list;
|
||||
while(search)
|
||||
{
|
||||
CollisionPair *coll_pair = search->link;
|
||||
|
||||
MEM_freeN(coll_pair);
|
||||
search = search->next;
|
||||
}
|
||||
BLI_linklist_free(collision_list,NULL);
|
||||
|
||||
collision_list = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("ic: %d\n", ic);
|
||||
rounds++;
|
||||
}
|
||||
while(result && (CLOTH_MAX_THRESHOLD>rounds));
|
||||
|
||||
printf("\n");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// update positions
|
||||
// this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// verts come from clmd
|
||||
for(i = 0; i < numverts; i++)
|
||||
{
|
||||
VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// moving collisions
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// update cloth bvh
|
||||
// bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING
|
||||
|
||||
// update moving bvh for collision object once
|
||||
for (base = G.scene->base.first; base; base = base->next)
|
||||
{
|
||||
|
||||
coll_ob = base->object;
|
||||
coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
|
||||
if (!coll_clmd)
|
||||
continue;
|
||||
|
||||
if(!coll_clmd->clothObject)
|
||||
continue;
|
||||
|
||||
// if collision object go on
|
||||
if (coll_clmd->clothObject && coll_clmd->clothObject->tree)
|
||||
{
|
||||
BVH *coll_bvh = coll_clmd->clothObject->tree;
|
||||
|
||||
// bvh_update(coll_clmd, coll_bvh, 1); // 0 means STATIC, 1 means MOVING
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
result = 0;
|
||||
ic = 0;
|
||||
|
||||
// check all collision objects
|
||||
for (base = G.scene->base.first; base; base = base->next)
|
||||
{
|
||||
coll_ob = base->object;
|
||||
coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
|
||||
|
||||
if (!coll_clmd)
|
||||
continue;
|
||||
|
||||
// if collision object go on
|
||||
if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
|
||||
{
|
||||
if (coll_clmd->clothObject && coll_clmd->clothObject->tree)
|
||||
{
|
||||
BVH *coll_bvh = coll_clmd->clothObject->tree;
|
||||
|
||||
bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list);
|
||||
|
||||
// process all collisions (calculate impulses, TODO: also repulses if distance too short)
|
||||
result = 1;
|
||||
for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence
|
||||
{
|
||||
result = 0;
|
||||
|
||||
// handle all collision objects
|
||||
|
||||
/*
|
||||
if (coll_clmd->clothObject)
|
||||
result += collisions_collision_response_moving_tris(clmd, coll_clmd);
|
||||
else
|
||||
printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
|
||||
*/
|
||||
|
||||
// apply impulses in parallel
|
||||
ic=0;
|
||||
for(i = 0; i < numverts; 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);
|
||||
VECCOPY(verts[i].impulse, tnull);
|
||||
verts[i].impulse_count = 0;
|
||||
|
||||
ic++;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// verts come from clmd
|
||||
for(i = 0; i < numverts; i++)
|
||||
{
|
||||
VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
|
||||
}
|
||||
|
||||
// update cloth bvh
|
||||
// bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING
|
||||
|
||||
|
||||
// free collision list
|
||||
if(collision_list)
|
||||
{
|
||||
LinkNode *search = collision_list;
|
||||
while(search)
|
||||
{
|
||||
CollisionPair *coll_pair = search->link;
|
||||
|
||||
MEM_freeN(coll_pair);
|
||||
search = search->next;
|
||||
}
|
||||
BLI_linklist_free(collision_list,NULL);
|
||||
|
||||
collision_list = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("ic: %d\n", ic);
|
||||
rounds++;
|
||||
}
|
||||
while(result && (CLOTH_MAX_THRESHOLD>rounds));
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// update positions + velocities
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// verts come from clmd
|
||||
for(i = 0; i < numverts; i++)
|
||||
{
|
||||
VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
return MIN2(ret, 1);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_threads.h"
|
||||
#include "BKE_collisions.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_effect.h"
|
||||
@@ -1585,3 +1586,841 @@ void implicit_set_positions (ClothModifierData *clmd)
|
||||
VECCOPY(id->V[i], verts[i].v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int collisions_collision_response_static(ClothModifierData *clmd, ClothModifierData *coll_clmd)
|
||||
{
|
||||
/*
|
||||
unsigned int i = 0;
|
||||
int result = 0;
|
||||
LinkNode *search = NULL;
|
||||
CollPair *collpair = NULL;
|
||||
Cloth *cloth1, *cloth2;
|
||||
float w1, w2, w3, u1, u2, u3;
|
||||
float v1[3], v2[3], relativeVelocity[3];
|
||||
float magrelVel;
|
||||
|
||||
cloth1 = clmd->clothObject;
|
||||
cloth2 = coll_clmd->clothObject;
|
||||
|
||||
// search = clmd->coll_parms.collision_list;
|
||||
|
||||
while(search)
|
||||
{
|
||||
collpair = search->link;
|
||||
|
||||
// compute barycentric coordinates for both collision points
|
||||
collisions_compute_barycentric(collpair->pa,
|
||||
cloth1->verts[collpair->ap1].txold,
|
||||
cloth1->verts[collpair->ap2].txold,
|
||||
cloth1->verts[collpair->ap3].txold,
|
||||
&w1, &w2, &w3);
|
||||
|
||||
collisions_compute_barycentric(collpair->pb,
|
||||
cloth2->verts[collpair->bp1].txold,
|
||||
cloth2->verts[collpair->bp2].txold,
|
||||
cloth2->verts[collpair->bp3].txold,
|
||||
&u1, &u2, &u3);
|
||||
|
||||
// Calculate relative "velocity".
|
||||
interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3);
|
||||
|
||||
interpolateOnTriangle(v2, cloth2->verts[collpair->bp1].tv, cloth2->verts[collpair->bp2].tv, cloth2->verts[collpair->bp3].tv, u1, u2, u3);
|
||||
|
||||
VECSUB(relativeVelocity, v1, v2);
|
||||
|
||||
// Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
|
||||
magrelVel = INPR(relativeVelocity, collpair->normal);
|
||||
|
||||
// printf("magrelVel: %f\n", magrelVel);
|
||||
|
||||
// Calculate masses of points.
|
||||
|
||||
// If v_n_mag < 0 the edges are approaching each other.
|
||||
if(magrelVel < -ALMOST_ZERO)
|
||||
{
|
||||
// Calculate Impulse magnitude to stop all motion in normal direction.
|
||||
// const double I_mag = v_n_mag / (1/m1 + 1/m2);
|
||||
float magnitude_i = magrelVel / 2.0f; // TODO implement masses
|
||||
float tangential[3], magtangent, magnormal, collvel[3];
|
||||
float vrel_t_pre[3];
|
||||
float vrel_t[3];
|
||||
double impulse;
|
||||
float epsilon = clmd->coll_parms.epsilon;
|
||||
float overlap = (epsilon + ALMOST_ZERO-collpair->distance);
|
||||
|
||||
// calculateFrictionImpulse(tangential, relativeVelocity, collpair->normal, magrelVel, clmd->coll_parms.friction*0.01, magrelVel);
|
||||
|
||||
// magtangent = INPR(tangential, tangential);
|
||||
|
||||
// Apply friction impulse.
|
||||
if (magtangent < -ALMOST_ZERO)
|
||||
{
|
||||
|
||||
// printf("friction applied: %f\n", magtangent);
|
||||
// TODO check original code
|
||||
}
|
||||
|
||||
|
||||
impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
|
||||
|
||||
// printf("impulse: %f\n", impulse);
|
||||
|
||||
// face A
|
||||
VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse);
|
||||
cloth1->verts[collpair->ap1].impulse_count++;
|
||||
|
||||
VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse);
|
||||
cloth1->verts[collpair->ap2].impulse_count++;
|
||||
|
||||
VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse);
|
||||
cloth1->verts[collpair->ap3].impulse_count++;
|
||||
|
||||
// face B
|
||||
VECADDMUL(cloth2->verts[collpair->bp1].impulse, collpair->normal, u1 * impulse);
|
||||
cloth2->verts[collpair->bp1].impulse_count++;
|
||||
|
||||
VECADDMUL(cloth2->verts[collpair->bp2].impulse, collpair->normal, u2 * impulse);
|
||||
cloth2->verts[collpair->bp2].impulse_count++;
|
||||
|
||||
VECADDMUL(cloth2->verts[collpair->bp3].impulse, collpair->normal, u3 * impulse);
|
||||
cloth2->verts[collpair->bp3].impulse_count++;
|
||||
|
||||
|
||||
result = 1;
|
||||
|
||||
// printf("magnitude_i: %f\n", magnitude_i); // negative before collision in my case
|
||||
|
||||
// Apply the impulse and increase impulse counters.
|
||||
|
||||
|
||||
}
|
||||
|
||||
search = search->next;
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int collisions_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int collisions_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
|
||||
{
|
||||
/*
|
||||
CollPair *collpair = NULL;
|
||||
Cloth *cloth1=NULL, *cloth2=NULL;
|
||||
MFace *face1=NULL, *face2=NULL;
|
||||
ClothVertex *verts1=NULL, *verts2=NULL;
|
||||
double distance = 0;
|
||||
float epsilon = clmd->coll_parms.epsilon;
|
||||
unsigned int i = 0;
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair");
|
||||
|
||||
cloth1 = clmd->clothObject;
|
||||
cloth2 = coll_clmd->clothObject;
|
||||
|
||||
verts1 = cloth1->verts;
|
||||
verts2 = cloth2->verts;
|
||||
|
||||
face1 = &(cloth1->mfaces[tree1->tri_index]);
|
||||
face2 = &(cloth2->mfaces[tree2->tri_index]);
|
||||
|
||||
// check all possible pairs of triangles
|
||||
if(i == 0)
|
||||
{
|
||||
collpair->ap1 = face1->v1;
|
||||
collpair->ap2 = face1->v2;
|
||||
collpair->ap3 = face1->v3;
|
||||
|
||||
collpair->bp1 = face2->v1;
|
||||
collpair->bp2 = face2->v2;
|
||||
collpair->bp3 = face2->v3;
|
||||
|
||||
}
|
||||
|
||||
if(i == 1)
|
||||
{
|
||||
if(face1->v4)
|
||||
{
|
||||
collpair->ap1 = face1->v3;
|
||||
collpair->ap2 = face1->v4;
|
||||
collpair->ap3 = face1->v1;
|
||||
|
||||
collpair->bp1 = face2->v1;
|
||||
collpair->bp2 = face2->v2;
|
||||
collpair->bp3 = face2->v3;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
if(i == 2)
|
||||
{
|
||||
if(face2->v4)
|
||||
{
|
||||
collpair->ap1 = face1->v1;
|
||||
collpair->ap2 = face1->v2;
|
||||
collpair->ap3 = face1->v3;
|
||||
|
||||
collpair->bp1 = face2->v3;
|
||||
collpair->bp2 = face2->v4;
|
||||
collpair->bp3 = face2->v1;
|
||||
}
|
||||
else
|
||||
i+=2;
|
||||
}
|
||||
|
||||
if(i == 3)
|
||||
{
|
||||
if((face1->v4)&&(face2->v4))
|
||||
{
|
||||
collpair->ap1 = face1->v3;
|
||||
collpair->ap2 = face1->v4;
|
||||
collpair->ap3 = face1->v1;
|
||||
|
||||
collpair->bp1 = face2->v3;
|
||||
collpair->bp2 = face2->v4;
|
||||
collpair->bp3 = face2->v1;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
// calc SIPcode (?)
|
||||
|
||||
if(i < 4)
|
||||
{
|
||||
// calc distance + normal
|
||||
distance = plNearestPoints(
|
||||
verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, verts2[collpair->bp1].txold, verts2[collpair->bp2].txold, verts2[collpair->bp3].txold, collpair->pa,collpair->pb,collpair->vector);
|
||||
|
||||
if (distance <= (epsilon + ALMOST_ZERO))
|
||||
{
|
||||
// printf("dist: %f\n", (float)distance);
|
||||
|
||||
// collpair->face1 = tree1->tri_index;
|
||||
// collpair->face2 = tree2->tri_index;
|
||||
|
||||
// VECCOPY(collpair->normal, collpair->vector);
|
||||
// Normalize(collpair->normal);
|
||||
|
||||
// collpair->distance = distance;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
MEM_freeN(collpair);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MEM_freeN(collpair);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int collisions_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair)
|
||||
{
|
||||
Cloth *cloth1, *cloth2;
|
||||
ClothVertex *verts1, *verts2;
|
||||
float temp[3];
|
||||
|
||||
cloth1 = clmd->clothObject;
|
||||
cloth2 = coll_clmd->clothObject;
|
||||
|
||||
verts1 = cloth1->verts;
|
||||
verts2 = cloth2->verts;
|
||||
|
||||
VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold);
|
||||
if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
|
||||
return 1;
|
||||
|
||||
VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold);
|
||||
if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
|
||||
return 1;
|
||||
|
||||
VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold);
|
||||
if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
|
||||
return 1;
|
||||
|
||||
VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold);
|
||||
if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void collisions_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
|
||||
{
|
||||
/*
|
||||
EdgeCollPair edgecollpair;
|
||||
Cloth *cloth1=NULL, *cloth2=NULL;
|
||||
MFace *face1=NULL, *face2=NULL;
|
||||
ClothVertex *verts1=NULL, *verts2=NULL;
|
||||
double distance = 0;
|
||||
float epsilon = clmd->coll_parms.epsilon;
|
||||
unsigned int i = 0, j = 0, k = 0;
|
||||
int numsolutions = 0;
|
||||
float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
|
||||
|
||||
cloth1 = clmd->clothObject;
|
||||
cloth2 = coll_clmd->clothObject;
|
||||
|
||||
verts1 = cloth1->verts;
|
||||
verts2 = cloth2->verts;
|
||||
|
||||
face1 = &(cloth1->mfaces[tree1->tri_index]);
|
||||
face2 = &(cloth2->mfaces[tree2->tri_index]);
|
||||
|
||||
for( i = 0; i < 5; i++)
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
edgecollpair.p11 = face1->v1;
|
||||
edgecollpair.p12 = face1->v2;
|
||||
}
|
||||
else if(i == 1)
|
||||
{
|
||||
edgecollpair.p11 = face1->v2;
|
||||
edgecollpair.p12 = face1->v3;
|
||||
}
|
||||
else if(i == 2)
|
||||
{
|
||||
if(face1->v4)
|
||||
{
|
||||
edgecollpair.p11 = face1->v3;
|
||||
edgecollpair.p12 = face1->v4;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgecollpair.p11 = face1->v3;
|
||||
edgecollpair.p12 = face1->v1;
|
||||
i+=5; // get out of here after this edge pair is handled
|
||||
}
|
||||
}
|
||||
else if(i == 3)
|
||||
{
|
||||
if(face1->v4)
|
||||
{
|
||||
edgecollpair.p11 = face1->v4;
|
||||
edgecollpair.p12 = face1->v1;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgecollpair.p11 = face1->v3;
|
||||
edgecollpair.p12 = face1->v1;
|
||||
}
|
||||
|
||||
|
||||
for( j = 0; j < 5; j++)
|
||||
{
|
||||
if(j == 0)
|
||||
{
|
||||
edgecollpair.p21 = face2->v1;
|
||||
edgecollpair.p22 = face2->v2;
|
||||
}
|
||||
else if(j == 1)
|
||||
{
|
||||
edgecollpair.p21 = face2->v2;
|
||||
edgecollpair.p22 = face2->v3;
|
||||
}
|
||||
else if(j == 2)
|
||||
{
|
||||
if(face2->v4)
|
||||
{
|
||||
edgecollpair.p21 = face2->v3;
|
||||
edgecollpair.p22 = face2->v4;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgecollpair.p21 = face2->v3;
|
||||
edgecollpair.p22 = face2->v1;
|
||||
}
|
||||
}
|
||||
else if(j == 3)
|
||||
{
|
||||
if(face2->v4)
|
||||
{
|
||||
edgecollpair.p21 = face2->v4;
|
||||
edgecollpair.p22 = face2->v1;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgecollpair.p21 = face2->v3;
|
||||
edgecollpair.p22 = face2->v1;
|
||||
}
|
||||
|
||||
|
||||
if(!collisions_are_edges_adjacent(clmd, coll_clmd, &edgecollpair))
|
||||
{
|
||||
VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold);
|
||||
VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v);
|
||||
VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold);
|
||||
VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v);
|
||||
VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold);
|
||||
VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v);
|
||||
|
||||
numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
|
||||
|
||||
for (k = 0; k < numsolutions; k++)
|
||||
{
|
||||
if ((solution[k] >= 0.0) && (solution[k] <= 1.0))
|
||||
{
|
||||
float out_collisionTime = solution[k];
|
||||
|
||||
// TODO: check for collisions
|
||||
|
||||
// TODO: put into (edge) collision list
|
||||
|
||||
printf("Moving edge found!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void collisions_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
|
||||
{
|
||||
/*
|
||||
CollPair collpair;
|
||||
Cloth *cloth1=NULL, *cloth2=NULL;
|
||||
MFace *face1=NULL, *face2=NULL;
|
||||
ClothVertex *verts1=NULL, *verts2=NULL;
|
||||
double distance = 0;
|
||||
float epsilon = clmd->coll_parms.epsilon;
|
||||
unsigned int i = 0, j = 0, k = 0;
|
||||
int numsolutions = 0;
|
||||
float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
|
||||
|
||||
for(i = 0; i < 2; i++)
|
||||
{
|
||||
cloth1 = clmd->clothObject;
|
||||
cloth2 = coll_clmd->clothObject;
|
||||
|
||||
verts1 = cloth1->verts;
|
||||
verts2 = cloth2->verts;
|
||||
|
||||
face1 = &(cloth1->mfaces[tree1->tri_index]);
|
||||
face2 = &(cloth2->mfaces[tree2->tri_index]);
|
||||
|
||||
// check all possible pairs of triangles
|
||||
if(i == 0)
|
||||
{
|
||||
collpair.ap1 = face1->v1;
|
||||
collpair.ap2 = face1->v2;
|
||||
collpair.ap3 = face1->v3;
|
||||
|
||||
collpair.pointsb[0] = face2->v1;
|
||||
collpair.pointsb[1] = face2->v2;
|
||||
collpair.pointsb[2] = face2->v3;
|
||||
collpair.pointsb[3] = face2->v4;
|
||||
}
|
||||
|
||||
if(i == 1)
|
||||
{
|
||||
if(face1->v4)
|
||||
{
|
||||
collpair.ap1 = face1->v3;
|
||||
collpair.ap2 = face1->v4;
|
||||
collpair.ap3 = face1->v1;
|
||||
|
||||
collpair.pointsb[0] = face2->v1;
|
||||
collpair.pointsb[1] = face2->v2;
|
||||
collpair.pointsb[2] = face2->v3;
|
||||
collpair.pointsb[3] = face2->v4;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
// calc SIPcode (?)
|
||||
|
||||
if(i < 2)
|
||||
{
|
||||
VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold);
|
||||
VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v);
|
||||
VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold);
|
||||
VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v);
|
||||
|
||||
for(j = 0; j < 4; j++)
|
||||
{
|
||||
if((j==3) && !(face2->v4))
|
||||
break;
|
||||
|
||||
VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold);
|
||||
VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v);
|
||||
|
||||
numsolutions = collisions_get_collision_time(a, b, c, d, e, f, solution);
|
||||
|
||||
for (k = 0; k < numsolutions; k++)
|
||||
{
|
||||
if ((solution[k] >= 0.0) && (solution[k] <= 1.0))
|
||||
{
|
||||
float out_collisionTime = solution[k];
|
||||
|
||||
// TODO: check for collisions
|
||||
|
||||
// TODO: put into (point-face) collision list
|
||||
|
||||
printf("Moving found!\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check borders for collisions
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// move collision objects forward in time and update static bounding boxes
|
||||
void collisions_update_collision_objects(float step)
|
||||
{
|
||||
Base *base=NULL;
|
||||
ClothModifierData *coll_clmd=NULL;
|
||||
Object *coll_ob=NULL;
|
||||
unsigned int i=0;
|
||||
|
||||
// search all objects for collision object
|
||||
for (base = G.scene->base.first; base; base = base->next)
|
||||
{
|
||||
|
||||
coll_ob = base->object;
|
||||
coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
|
||||
if (!coll_clmd)
|
||||
continue;
|
||||
|
||||
// if collision object go on
|
||||
if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
|
||||
{
|
||||
if (coll_clmd->clothObject && coll_clmd->clothObject->tree)
|
||||
{
|
||||
Cloth *coll_cloth = coll_clmd->clothObject;
|
||||
BVH *coll_bvh = coll_clmd->clothObject->tree;
|
||||
unsigned int coll_numverts = coll_cloth->numverts;
|
||||
|
||||
// update position of collision object
|
||||
for(i = 0; i < coll_numverts; i++)
|
||||
{
|
||||
VECCOPY(coll_cloth->verts[i].txold, coll_cloth->verts[i].tx);
|
||||
|
||||
VECADDS(coll_cloth->verts[i].tx, coll_cloth->verts[i].xold, coll_cloth->verts[i].v, step);
|
||||
|
||||
// no dt here because of float rounding errors
|
||||
VECSUB(coll_cloth->verts[i].tv, coll_cloth->verts[i].tx, coll_cloth->verts[i].txold);
|
||||
}
|
||||
|
||||
// update BVH of collision object
|
||||
// bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING
|
||||
}
|
||||
else
|
||||
printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void collisions_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
|
||||
{
|
||||
/*
|
||||
// TODO: check for adjacent
|
||||
collisions_collision_moving_edges(clmd, coll_clmd, tree1, tree2);
|
||||
|
||||
collisions_collision_moving_tris(clmd, coll_clmd, tree1, tree2);
|
||||
collisions_collision_moving_tris(coll_clmd, clmd, tree2, tree1);
|
||||
*/
|
||||
}
|
||||
|
||||
// cloth - object collisions
|
||||
int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
|
||||
{
|
||||
/*
|
||||
Base *base=NULL;
|
||||
ClothModifierData *coll_clmd=NULL;
|
||||
Cloth *cloth=NULL;
|
||||
Object *coll_ob=NULL;
|
||||
BVH *collisions_bvh=NULL;
|
||||
unsigned int 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;
|
||||
LinkNode *collision_list = NULL;
|
||||
|
||||
if ((clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cloth = clmd->clothObject;
|
||||
verts = cloth->verts;
|
||||
collisions_bvh = (BVH *) cloth->tree;
|
||||
numfaces = clmd->clothObject->numfaces;
|
||||
numverts = clmd->clothObject->numverts;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// static collisions
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// update cloth bvh
|
||||
// bvh_update(clmd, collisions_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
|
||||
|
||||
// update collision objects
|
||||
collisions_update_collision_objects(step);
|
||||
|
||||
do
|
||||
{
|
||||
result = 0;
|
||||
ic = 0;
|
||||
|
||||
// check all collision objects
|
||||
for (base = G.scene->base.first; base; base = base->next)
|
||||
{
|
||||
coll_ob = base->object;
|
||||
coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
|
||||
|
||||
if (!coll_clmd)
|
||||
continue;
|
||||
|
||||
// if collision object go on
|
||||
if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
|
||||
{
|
||||
if (coll_clmd->clothObject && coll_clmd->clothObject->tree)
|
||||
{
|
||||
BVH *coll_bvh = coll_clmd->clothObject->tree;
|
||||
|
||||
// fill collision list
|
||||
bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list);
|
||||
|
||||
// process all collisions (calculate impulses, TODO: also repulses if distance too short)
|
||||
result = 1;
|
||||
for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence
|
||||
{
|
||||
result = 0;
|
||||
|
||||
// result += collisions_collision_response_static_tris(clmd, coll_clmd, collision_list, 0);
|
||||
|
||||
// result += collisions_collision_response_static_tris(coll_clmd, clmd, collision_list, 1);
|
||||
|
||||
// apply impulses in parallel
|
||||
ic=0;
|
||||
for(i = 0; i < numverts; 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);
|
||||
VECCOPY(verts[i].impulse, tnull);
|
||||
verts[i].impulse_count = 0;
|
||||
|
||||
ic++;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// free collision list
|
||||
if(collision_list)
|
||||
{
|
||||
LinkNode *search = collision_list;
|
||||
while(search)
|
||||
{
|
||||
CollisionPair *coll_pair = search->link;
|
||||
|
||||
MEM_freeN(coll_pair);
|
||||
search = search->next;
|
||||
}
|
||||
BLI_linklist_free(collision_list,NULL);
|
||||
|
||||
collision_list = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("ic: %d\n", ic);
|
||||
rounds++;
|
||||
}
|
||||
while(result && (10>rounds));// CLOTH_MAX_THRESHOLD
|
||||
|
||||
printf("\n");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// update positions
|
||||
// this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// verts come from clmd
|
||||
for(i = 0; i < numverts; i++)
|
||||
{
|
||||
VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// moving collisions
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// update cloth bvh
|
||||
// bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING
|
||||
|
||||
// update moving bvh for collision object once
|
||||
for (base = G.scene->base.first; base; base = base->next)
|
||||
{
|
||||
|
||||
coll_ob = base->object;
|
||||
coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
|
||||
if (!coll_clmd)
|
||||
continue;
|
||||
|
||||
if(!coll_clmd->clothObject)
|
||||
continue;
|
||||
|
||||
// if collision object go on
|
||||
if (coll_clmd->clothObject && coll_clmd->clothObject->tree)
|
||||
{
|
||||
BVH *coll_bvh = coll_clmd->clothObject->tree;
|
||||
|
||||
// bvh_update(coll_clmd, coll_bvh, 1); // 0 means STATIC, 1 means MOVING
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
result = 0;
|
||||
ic = 0;
|
||||
|
||||
// check all collision objects
|
||||
for (base = G.scene->base.first; base; base = base->next)
|
||||
{
|
||||
coll_ob = base->object;
|
||||
coll_clmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
|
||||
|
||||
if (!coll_clmd)
|
||||
continue;
|
||||
|
||||
// if collision object go on
|
||||
if (coll_clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
|
||||
{
|
||||
if (coll_clmd->clothObject && coll_clmd->clothObject->tree)
|
||||
{
|
||||
BVH *coll_bvh = coll_clmd->clothObject->tree;
|
||||
|
||||
bvh_traverse(collisions_bvh->root, coll_bvh->root, collision_list);
|
||||
|
||||
// process all collisions (calculate impulses, TODO: also repulses if distance too short)
|
||||
result = 1;
|
||||
for(j = 0; j < 10; j++) // 10 is just a value that ensures convergence
|
||||
{
|
||||
result = 0;
|
||||
|
||||
// handle all collision objects
|
||||
|
||||
|
||||
if (coll_clmd->clothObject)
|
||||
result += collisions_collision_response_moving_tris(clmd, coll_clmd);
|
||||
else
|
||||
printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
|
||||
|
||||
|
||||
// apply impulses in parallel
|
||||
ic=0;
|
||||
for(i = 0; i < numverts; 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);
|
||||
VECCOPY(verts[i].impulse, tnull);
|
||||
verts[i].impulse_count = 0;
|
||||
|
||||
ic++;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// verts come from clmd
|
||||
for(i = 0; i < numverts; i++)
|
||||
{
|
||||
VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
|
||||
}
|
||||
|
||||
// update cloth bvh
|
||||
// bvh_update(clmd, collisions_bvh, 1); // 0 means STATIC, 1 means MOVING
|
||||
|
||||
|
||||
// free collision list
|
||||
if(collision_list)
|
||||
{
|
||||
LinkNode *search = collision_list;
|
||||
while(search)
|
||||
{
|
||||
CollisionPair *coll_pair = search->link;
|
||||
|
||||
MEM_freeN(coll_pair);
|
||||
search = search->next;
|
||||
}
|
||||
BLI_linklist_free(collision_list,NULL);
|
||||
|
||||
collision_list = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
printf ("collisions_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("ic: %d\n", ic);
|
||||
rounds++;
|
||||
}
|
||||
while(result && (10>rounds)); // CLOTH_MAX_THRESHOLD
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// update positions + velocities
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// verts come from clmd
|
||||
for(i = 0; i < numverts; i++)
|
||||
{
|
||||
VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
return MIN2(ret, 1);
|
||||
*/
|
||||
}
|
||||
@@ -164,9 +164,9 @@ static int size_threshold = 16;
|
||||
/*
|
||||
* Common methods for all algorithms
|
||||
*/
|
||||
void bvh_exchange(Tree **a, int i, int j)
|
||||
void bvh_exchange(CollisionTree **a, int i, int j)
|
||||
{
|
||||
Tree *t=a[i];
|
||||
CollisionTree *t=a[i];
|
||||
a[i]=a[j];
|
||||
a[j]=t;
|
||||
}
|
||||
@@ -178,10 +178,10 @@ int floor_lg(int a)
|
||||
/*
|
||||
* Insertion sort algorithm
|
||||
*/
|
||||
static void bvh_insertionsort(Tree **a, int lo, int hi, int axis)
|
||||
static void bvh_insertionsort(CollisionTree **a, int lo, int hi, int axis)
|
||||
{
|
||||
int i,j;
|
||||
Tree *t;
|
||||
CollisionTree *t;
|
||||
for (i=lo; i < hi; i++)
|
||||
{
|
||||
j=i;
|
||||
@@ -195,7 +195,7 @@ static void bvh_insertionsort(Tree **a, int lo, int hi, int axis)
|
||||
}
|
||||
}
|
||||
|
||||
static int bvh_partition(Tree **a, int lo, int hi, Tree * x, int axis)
|
||||
static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree *x, int axis)
|
||||
{
|
||||
int i=lo, j=hi;
|
||||
while (1)
|
||||
@@ -213,9 +213,9 @@ static int bvh_partition(Tree **a, int lo, int hi, Tree * x, int axis)
|
||||
/*
|
||||
* Heapsort algorithm
|
||||
*/
|
||||
static void bvh_downheap(Tree **a, int i, int n, int lo, int axis)
|
||||
static void bvh_downheap(CollisionTree **a, int i, int n, int lo, int axis)
|
||||
{
|
||||
Tree * d = a[lo+i-1];
|
||||
CollisionTree *d = a[lo+i-1];
|
||||
int child;
|
||||
while (i<=n/2)
|
||||
{
|
||||
@@ -231,7 +231,7 @@ static void bvh_downheap(Tree **a, int i, int n, int lo, int axis)
|
||||
a[lo+i-1] = d;
|
||||
}
|
||||
|
||||
static void bvh_heapsort(Tree **a, int lo, int hi, int axis)
|
||||
static void bvh_heapsort(CollisionTree **a, int lo, int hi, int axis)
|
||||
{
|
||||
int n = hi-lo, i;
|
||||
for (i=n/2; i>=1; i=i-1)
|
||||
@@ -245,7 +245,7 @@ static void bvh_heapsort(Tree **a, int lo, int hi, int axis)
|
||||
}
|
||||
}
|
||||
|
||||
static Tree *bvh_medianof3(Tree **a, int lo, int mid, int hi, int axis) // returns Sortable
|
||||
static CollisionTree *bvh_medianof3(CollisionTree **a, int lo, int mid, int hi, int axis) // returns Sortable
|
||||
{
|
||||
if ((a[mid])->bv[axis] < (a[lo])->bv[axis])
|
||||
{
|
||||
@@ -275,7 +275,7 @@ static Tree *bvh_medianof3(Tree **a, int lo, int mid, int hi, int axis) // retur
|
||||
/*
|
||||
* Quicksort algorithm modified for Introsort
|
||||
*/
|
||||
static void bvh_introsort_loop (Tree **a, int lo, int hi, int depth_limit, int axis)
|
||||
static void bvh_introsort_loop (CollisionTree **a, int lo, int hi, int depth_limit, int axis)
|
||||
{
|
||||
int p;
|
||||
|
||||
@@ -293,16 +293,16 @@ static void bvh_introsort_loop (Tree **a, int lo, int hi, int depth_limit, int a
|
||||
}
|
||||
}
|
||||
|
||||
void bvh_sort(Tree **a0, int begin, int end, int axis)
|
||||
void bvh_sort(CollisionTree **a0, int begin, int end, int axis)
|
||||
{
|
||||
if (begin < end)
|
||||
{
|
||||
Tree **a=a0;
|
||||
CollisionTree **a=a0;
|
||||
bvh_introsort_loop(a, begin, end, 2*floor_lg(end-begin), axis);
|
||||
bvh_insertionsort(a, begin, end, axis);
|
||||
}
|
||||
}
|
||||
void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis)
|
||||
void bvh_sort_along_axis(CollisionTree **face_list, int start, int end, int axis)
|
||||
{
|
||||
bvh_sort(face_list, start, end, axis);
|
||||
}
|
||||
@@ -310,7 +310,7 @@ void bvh_sort_along_axis(Tree **face_list, int start, int end, int axis)
|
||||
void bvh_free(BVH * bvh)
|
||||
{
|
||||
LinkNode *search = NULL;
|
||||
Tree *tree = NULL;
|
||||
CollisionTree *tree = NULL;
|
||||
|
||||
if (bvh)
|
||||
{
|
||||
@@ -361,7 +361,7 @@ int bvh_largest_axis(float *bv)
|
||||
}
|
||||
|
||||
// depends on the fact that the BVH's for each face is already build
|
||||
void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv)
|
||||
void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
|
||||
{
|
||||
float newmin,newmax;
|
||||
int i, j;
|
||||
@@ -385,32 +385,22 @@ void bvh_calc_DOP_hull_from_faces(BVH * bvh, Tree **tri, int numfaces, float *bv
|
||||
}
|
||||
}
|
||||
|
||||
void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv)
|
||||
void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
|
||||
{
|
||||
MVert *tempMVert = bvh->x;
|
||||
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;
|
||||
// 3 or 4 vertices per face.
|
||||
// 1 up to 4 vertices per leaf.
|
||||
for (k = 0; k < 4; k++)
|
||||
{
|
||||
int temp = 0;
|
||||
// If this is a triangle.
|
||||
if (k == 3 && !tempMFace->v4)
|
||||
int temp = tri[j]->point_index[k];
|
||||
|
||||
if(temp < 0)
|
||||
continue;
|
||||
// TODO: other name for "temp" this gets all vertices of a face
|
||||
if (k == 0)
|
||||
temp = tempMFace->v1;
|
||||
else if (k == 1)
|
||||
temp = tempMFace->v2;
|
||||
else if (k == 2)
|
||||
temp = tempMFace->v3;
|
||||
else if (k == 3)
|
||||
temp = tempMFace->v4;
|
||||
|
||||
// for all Axes.
|
||||
for (i = KDOP_START; i < KDOP_END; i++)
|
||||
{
|
||||
@@ -424,33 +414,23 @@ void bvh_calc_DOP_hull_static(BVH * bvh, Tree **tri, int numfaces, float *bv)
|
||||
}
|
||||
}
|
||||
|
||||
void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv)
|
||||
void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
|
||||
{
|
||||
MVert *tempMVert = bvh->x;
|
||||
MVert *tempMVert2 = bvh->xnew;
|
||||
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;
|
||||
// 3 or 4 vertices per face.
|
||||
for (k = 0; k < 4; k++)
|
||||
{
|
||||
int temp = 0;
|
||||
// If this is a triangle.
|
||||
if (k == 3 && !tempMFace->v4)
|
||||
int temp = tri[j]->point_index[k];
|
||||
|
||||
if(temp < 0)
|
||||
continue;
|
||||
// TODO: other name for "temp" this gets all vertices of a face
|
||||
if (k == 0)
|
||||
temp = tempMFace->v1;
|
||||
else if (k == 1)
|
||||
temp = tempMFace->v2;
|
||||
else if (k == 2)
|
||||
temp = tempMFace->v3;
|
||||
else if (k == 3)
|
||||
temp = tempMFace->v4;
|
||||
|
||||
// for all Axes.
|
||||
for (i = KDOP_START; i < KDOP_END; i++)
|
||||
{
|
||||
@@ -470,10 +450,10 @@ void bvh_calc_DOP_hull_moving(BVH * bvh, Tree **tri, int numfaces, float *bv)
|
||||
}
|
||||
}
|
||||
|
||||
static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink)
|
||||
static void bvh_div_env_node(BVH * bvh, TreeNode *tree, CollisionTree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink)
|
||||
{
|
||||
int i = 0;
|
||||
Tree *newtree = NULL;
|
||||
CollisionTree *newtree = NULL;
|
||||
int laxis = 0, max_nodes=4;
|
||||
unsigned int tstart, tend;
|
||||
LinkNode *nlink1 = nlink;
|
||||
@@ -512,7 +492,7 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign
|
||||
// Build tree until 4 node left.
|
||||
if ((tend-tstart + 1 ) > 1)
|
||||
{
|
||||
newtree = (Tree *)MEM_callocN(sizeof(Tree), "Tree");
|
||||
newtree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
|
||||
tnlink = BLI_linklist_append_fast(&nlink1->next, newtree);
|
||||
|
||||
newtree->nodes[0] = newtree->nodes[1] = newtree->nodes[2] = newtree->nodes[3] = NULL;
|
||||
@@ -530,7 +510,7 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign
|
||||
}
|
||||
else // ok, we have 1 left for this node
|
||||
{
|
||||
Tree *tnode = face_list[tstart];
|
||||
CollisionTree *tnode = face_list[tstart];
|
||||
tree->nodes[i] = tnode;
|
||||
tree->nodes[i]->parent = tree;
|
||||
}
|
||||
@@ -538,19 +518,16 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, Tree **face_list, unsign
|
||||
return;
|
||||
}
|
||||
|
||||
BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, float epsilon)
|
||||
// mfaces is allowed to be null
|
||||
// just vertexes are used if mfaces=NULL
|
||||
BVH *bvh_build (MFace *mfaces, unsigned int numfaces, MVert *x, MVert *xnew, unsigned int numverts, float epsilon)
|
||||
{
|
||||
unsigned int i = 0, j = 0, k = 0;
|
||||
Tree **face_list=NULL;
|
||||
unsigned int i = 0, j = 0;
|
||||
CollisionTree **face_list=NULL;
|
||||
BVH *bvh=NULL;
|
||||
Tree *tree=NULL;
|
||||
CollisionTree *tree=NULL;
|
||||
LinkNode *nlink = NULL;
|
||||
EdgeHash *edgehash = NULL;
|
||||
unsigned int numsprings = 0;
|
||||
MFace *mface = NULL;
|
||||
|
||||
if(!dm)
|
||||
return NULL;
|
||||
|
||||
bvh = MEM_callocN(sizeof(BVH), "BVH");
|
||||
if (bvh == NULL)
|
||||
@@ -565,13 +542,19 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f
|
||||
bvh->tree = NULL;
|
||||
|
||||
bvh->epsilon = epsilon;
|
||||
bvh->numfaces = dm->getNumFaces(dm);
|
||||
mface = bvh->mfaces = dm->getFaceArray(dm);
|
||||
bvh->numfaces = numfaces;
|
||||
mface = bvh->mfaces = mfaces;
|
||||
|
||||
// we have no faces, we save seperate points
|
||||
if(!bvh->mfaces)
|
||||
{
|
||||
bvh->numfaces = numverts;
|
||||
}
|
||||
|
||||
bvh->numverts = numverts;
|
||||
bvh->xnew = xnew;
|
||||
bvh->x = x;
|
||||
tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree");
|
||||
tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
|
||||
// TODO: check succesfull alloc
|
||||
BLI_linklist_append(&bvh->tree, tree);
|
||||
|
||||
@@ -590,7 +573,25 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f
|
||||
|
||||
if(bvh->numfaces<=1)
|
||||
{
|
||||
bvh->root->tri_index = 0; // Why that? --> only one face there
|
||||
// Why that? --> only one face there
|
||||
if(bvh->mfaces)
|
||||
{
|
||||
bvh->root->point_index[0] = mfaces[0].v1;
|
||||
bvh->root->point_index[1] = mfaces[0].v2;
|
||||
bvh->root->point_index[2] = mfaces[0].v3;
|
||||
if(mfaces[0].v4)
|
||||
bvh->root->point_index[3] = mfaces[0].v4;
|
||||
else
|
||||
bvh->root->point_index[3] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bvh->root->point_index[0] = 0;
|
||||
bvh->root->point_index[1] = -1;
|
||||
bvh->root->point_index[2] = -1;
|
||||
bvh->root->point_index[3] = -1;
|
||||
}
|
||||
|
||||
bvh->root->isleaf = 1;
|
||||
bvh->root->traversed = 0;
|
||||
bvh->root->count_nodes = 0;
|
||||
@@ -602,7 +603,7 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f
|
||||
else
|
||||
{
|
||||
// create face boxes
|
||||
face_list = MEM_callocN (bvh->numfaces * sizeof (Tree *), "Tree");
|
||||
face_list = MEM_callocN (bvh->numfaces * sizeof (CollisionTree *), "CollisionTree");
|
||||
if (face_list == NULL)
|
||||
{
|
||||
printf("bvh_build: Out of memory for face_list.\n");
|
||||
@@ -611,17 +612,35 @@ BVH *bvh_build (DerivedMesh *dm, MVert *x, MVert *xnew, unsigned int numverts, f
|
||||
}
|
||||
|
||||
// create face boxes
|
||||
for(i = 0, k = 0; i < bvh->numfaces; i++)
|
||||
for(i = 0; i < bvh->numfaces; i++)
|
||||
{
|
||||
LinkNode *tnlink = NULL;
|
||||
|
||||
tree = (Tree *)MEM_callocN(sizeof(Tree), "Tree");
|
||||
tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
|
||||
// TODO: check succesfull alloc
|
||||
|
||||
tnlink = BLI_linklist_append_fast(&nlink->next, tree);
|
||||
|
||||
face_list[i] = tree;
|
||||
tree->tri_index = i;
|
||||
|
||||
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;
|
||||
if(mfaces[i].v4)
|
||||
bvh->root->point_index[3] = mfaces[i].v4;
|
||||
else
|
||||
bvh->root->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->isleaf = 1;
|
||||
tree->nextLeaf = NULL;
|
||||
tree->prevLeaf = bvh->leaf_tree;
|
||||
@@ -694,7 +713,7 @@ int bvh_overlap(float *bv1, float *bv2)
|
||||
* every other triangle that doesn't require any realloc, but uses
|
||||
* much memory
|
||||
*/
|
||||
int bvh_traverse(Tree * tree1, Tree * tree2, LinkNode *collision_list)
|
||||
int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode *collision_list)
|
||||
{
|
||||
int i = 0, ret = 0;
|
||||
|
||||
@@ -709,8 +728,11 @@ int bvh_traverse(Tree * tree1, Tree * tree2, LinkNode *collision_list)
|
||||
// save potential colliding triangles
|
||||
CollisionPair *collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
|
||||
|
||||
collpair->indexA = tree1->tri_index;
|
||||
collpair->indexB = tree2->tri_index;
|
||||
VECCOPY(collpair->point_indexA, tree1->point_index);
|
||||
collpair->point_indexA[3] = tree1->point_index[3];
|
||||
|
||||
VECCOPY(collpair->point_indexB, tree2->point_index);
|
||||
collpair->point_indexB[3] = tree2->point_index[3];
|
||||
|
||||
BLI_linklist_append(&collision_list, collpair);
|
||||
|
||||
@@ -744,7 +766,7 @@ int bvh_traverse(Tree * tree1, Tree * tree2, LinkNode *collision_list)
|
||||
|
||||
// bottom up update of bvh tree:
|
||||
// join the 4 children here
|
||||
void bvh_join(Tree * tree)
|
||||
void bvh_join(CollisionTree *tree)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
if (!tree)
|
||||
@@ -775,17 +797,12 @@ void bvh_join(Tree * tree)
|
||||
|
||||
// update static bvh
|
||||
// needs new positions in bvh->x, bvh->xnew
|
||||
void bvh_update(DerivedMesh *dm, BVH * bvh, int moving)
|
||||
void bvh_update(BVH * bvh, int moving)
|
||||
{
|
||||
TreeNode *leaf, *parent;
|
||||
int traversecheck = 1; // if this is zero we don't go further
|
||||
unsigned int j = 0;
|
||||
|
||||
if(bvh->numfaces != dm->getNumFaces(dm))
|
||||
return;
|
||||
|
||||
bvh->mfaces = dm->getFaceArray(dm);
|
||||
|
||||
for (leaf = bvh->leaf_root; leaf; leaf = leaf->nextLeaf)
|
||||
{
|
||||
traversecheck = 1;
|
||||
|
||||
@@ -4866,7 +4866,7 @@ static void clothModifier_initData(ModifierData *md)
|
||||
ClothModifierData *clmd = (ClothModifierData*) md;
|
||||
cloth_init (clmd);
|
||||
}
|
||||
|
||||
/*
|
||||
static void clothModifier_deformVerts(
|
||||
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||
float (*vertexCos)[3], int numVerts)
|
||||
@@ -4889,6 +4889,22 @@ static void clothModifier_deformVerts(
|
||||
if(dm)
|
||||
dm->release(dm);
|
||||
}
|
||||
*/
|
||||
|
||||
static DerivedMesh *clothModifier_applyModifier(
|
||||
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||
int useRenderParams, int isFinalCalc)
|
||||
{
|
||||
DerivedMesh *result = NULL;
|
||||
|
||||
ClothModifierData *clmd = (ClothModifierData*) md;
|
||||
|
||||
result = clothModifier_do(clmd, ob, derivedData);
|
||||
|
||||
CDDM_calc_normals(result);
|
||||
|
||||
return derivedData;
|
||||
}
|
||||
|
||||
static void clothModifier_updateDepgraph(
|
||||
ModifierData *md, DagForest *forest, Object *ob,
|
||||
@@ -4957,6 +4973,8 @@ static void collisionModifier_initData(ModifierData *md)
|
||||
|
||||
collmd->x = NULL;
|
||||
collmd->xnew = NULL;
|
||||
collmd->current_x = NULL;
|
||||
collmd->current_xnew = NULL;
|
||||
collmd->time = -1;
|
||||
collmd->numverts = 0;
|
||||
collmd->tree = NULL;
|
||||
@@ -4974,22 +4992,32 @@ static void collisionModifier_freeData(ModifierData *md)
|
||||
MEM_freeN(collmd->x);
|
||||
if(collmd->xnew)
|
||||
MEM_freeN(collmd->xnew);
|
||||
if(collmd->current_x)
|
||||
MEM_freeN(collmd->current_x);
|
||||
if(collmd->current_xnew)
|
||||
MEM_freeN(collmd->current_xnew);
|
||||
|
||||
collmd->x = NULL;
|
||||
collmd->xnew = NULL;
|
||||
collmd->current_x = NULL;
|
||||
collmd->current_xnew = NULL;
|
||||
collmd->time = -1;
|
||||
collmd->numverts = 0;
|
||||
collmd->tree = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int collisionModifier_dependsOnTime(ModifierData *md)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void collisionModifier_deformVerts(
|
||||
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||
float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
CollisionModifierData *collmd = (CollisionModifierData*) md;
|
||||
DerivedMesh *dm = NULL;
|
||||
MVert *mvert = NULL;
|
||||
float current_time = 0;
|
||||
unsigned int numverts = 0, i = 0;
|
||||
MVert *tempVert = NULL;
|
||||
@@ -4999,6 +5027,12 @@ static void collisionModifier_deformVerts(
|
||||
if(derivedData) dm = CDDM_copy(derivedData);
|
||||
else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
|
||||
|
||||
if(!ob->pd)
|
||||
{
|
||||
printf("collisionModifier_deformVerts: Should not happen!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(dm)
|
||||
{
|
||||
CDDM_apply_vert_coords(dm, vertexCos);
|
||||
@@ -5013,17 +5047,26 @@ static void collisionModifier_deformVerts(
|
||||
|
||||
// check if mesh has changed
|
||||
if(collmd->x && (numverts != collmd->numverts))
|
||||
collisionModifier_freeData(collmd);
|
||||
collisionModifier_freeData((ModifierData *)collmd);
|
||||
|
||||
if(collmd->time == -1) // first time
|
||||
{
|
||||
collmd->x = dm->dupVertArray(dm);
|
||||
collmd->xnew = dm->dupVertArray(dm);
|
||||
collmd->x = dm->dupVertArray(dm); // frame start position
|
||||
|
||||
for ( i = 0; i < numverts; i++ )
|
||||
{
|
||||
// we save global positions
|
||||
Mat4MulVecfl ( ob->obmat, collmd->x[i].co );
|
||||
}
|
||||
|
||||
collmd->xnew = MEM_dupallocN(collmd->x); // frame end position
|
||||
collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame
|
||||
collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
|
||||
collmd->numverts = numverts;
|
||||
|
||||
// TODO: epsilon
|
||||
// create bounding box hierarchy
|
||||
collmd->tree = bvh_build(dm, collmd->x, collmd->xnew, numverts, 0.01);
|
||||
collmd->tree = bvh_build(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->current_x, collmd->current_xnew, numverts, ob->pd->pdef_sbift);
|
||||
}
|
||||
else if(numverts == collmd->numverts)
|
||||
{
|
||||
@@ -5040,7 +5083,10 @@ static void collisionModifier_deformVerts(
|
||||
Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co );
|
||||
}
|
||||
|
||||
bvh_update(dm, collmd->tree, 0); // recalc static bounding boxes
|
||||
memcpy(collmd->current_xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
|
||||
memcpy(collmd->current_x, dm->getVertArray(dm), numverts*sizeof(MVert));
|
||||
|
||||
bvh_update(collmd->tree, 0); // recalc static bounding boxes
|
||||
}
|
||||
|
||||
collmd->time = current_time;
|
||||
@@ -5051,11 +5097,6 @@ static void collisionModifier_deformVerts(
|
||||
dm->release(dm);
|
||||
}
|
||||
|
||||
static int collisionModifier_dependsOnTime(ModifierData *md)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Boolean */
|
||||
|
||||
static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
@@ -5342,10 +5383,10 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
|
||||
mti->deformVerts = softbodyModifier_deformVerts;
|
||||
|
||||
mti = INIT_TYPE(Cloth);
|
||||
mti->type = eModifierTypeType_OnlyDeform;
|
||||
mti->type = eModifierTypeType_Nonconstructive;
|
||||
mti->initData = clothModifier_initData;
|
||||
mti->flags = eModifierTypeFlag_AcceptsCVs;
|
||||
// | eModifierTypeFlag_RequiresOriginalData;
|
||||
mti->flags = eModifierTypeFlag_AcceptsMesh
|
||||
| eModifierTypeFlag_RequiresOriginalData;
|
||||
// | eModifierTypeFlag_SupportsMapping
|
||||
// | eModifierTypeFlag_SupportsEditmode
|
||||
// | eModifierTypeFlag_EnableInEditmode;
|
||||
@@ -5353,7 +5394,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
|
||||
mti->freeData = clothModifier_freeData;
|
||||
mti->requiredDataMask = clothModifier_requiredDataMask;
|
||||
// mti->copyData = clothModifier_copyData;
|
||||
mti->deformVerts = clothModifier_deformVerts;
|
||||
// mti->deformVerts = clothModifier_deformVerts;
|
||||
mti->applyModifier = clothModifier_applyModifier;
|
||||
mti->updateDepgraph = clothModifier_updateDepgraph;
|
||||
|
||||
mti = INIT_TYPE(Collision);
|
||||
@@ -5567,11 +5609,11 @@ int modifiers_isSoftbodyEnabled(Object *ob)
|
||||
return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
|
||||
}
|
||||
|
||||
ModifierData *modifiers_isClothEnabled(Object *ob)
|
||||
ClothModifierData *modifiers_isClothEnabled(Object *ob)
|
||||
{
|
||||
ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
|
||||
ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
|
||||
|
||||
return md;
|
||||
return clmd;
|
||||
}
|
||||
|
||||
LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
|
||||
|
||||
@@ -2893,6 +2893,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
||||
|
||||
collmd->x = NULL;
|
||||
collmd->xnew = NULL;
|
||||
collmd->current_x = NULL;
|
||||
collmd->current_xnew = NULL;
|
||||
collmd->time = -1;
|
||||
collmd->numverts = 0;
|
||||
collmd->tree = NULL;
|
||||
@@ -3009,7 +3011,6 @@ static void direct_link_object(FileData *fd, Object *ob)
|
||||
sb->bpoint= NULL; // init pointers so it gets rebuilt nicely
|
||||
sb->bspring= NULL;
|
||||
sb->scratch= NULL;
|
||||
|
||||
|
||||
sb->keys= newdataadr(fd, sb->keys);
|
||||
test_pointer_array(fd, (void **)&sb->keys);
|
||||
|
||||
@@ -156,9 +156,13 @@ typedef struct Cloth
|
||||
unsigned char old_solver_type;
|
||||
unsigned char pad2;
|
||||
short pad3;
|
||||
void *tree; /* collision tree for this cloth object */
|
||||
struct CollisionTree *tree; /* collision tree for this cloth object */
|
||||
struct MFace *mfaces;
|
||||
void *implicit; /* our implicit solver connects to this pointer */
|
||||
struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */
|
||||
struct MVert *x;
|
||||
struct MVert *xnew;
|
||||
struct MVert *current_x;
|
||||
struct MVert *current_xnew;
|
||||
}
|
||||
Cloth;
|
||||
|
||||
|
||||
@@ -350,12 +350,14 @@ typedef struct ClothModifierData {
|
||||
typedef struct CollisionModifierData {
|
||||
ModifierData modifier;
|
||||
|
||||
struct MVert *x;
|
||||
struct MVert *xnew;
|
||||
struct MVert *x; /* position at the beginning of the frame */
|
||||
struct MVert *xnew; /* position at the end of the frame */
|
||||
struct MVert *current_xnew; /* new position at the actual inter-frame step */
|
||||
struct MVert *current_x; /* position at the actual inter-frame step */
|
||||
|
||||
unsigned int numverts;
|
||||
float time;
|
||||
void *tree; /* collision tree for this cloth object */
|
||||
struct BVH *tree; /* collision tree for this cloth object */
|
||||
} CollisionModifierData;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -113,7 +113,6 @@ typedef struct SoftBody {
|
||||
;
|
||||
|
||||
struct SBScratch *scratch; /* scratch pad/cache on live time not saved in file */
|
||||
|
||||
} SoftBody;
|
||||
|
||||
/* pd->forcefield: Effector Fields types */
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_booleanops.h"
|
||||
#include "BKE_cloth.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
|
||||
Reference in New Issue
Block a user