Replace MFace w/ vert-tri's for collision modifier
Note that the collision modifier doesn't have any use for Loop indices, so to avoid duplicating the loop array too, MVertTri has been added which simply stores vertex indices (runtime only).
This commit is contained in:
@@ -613,6 +613,7 @@ void DM_ensure_tessface(DerivedMesh *dm);
|
||||
|
||||
void DM_ensure_looptri_data(DerivedMesh *dm);
|
||||
void DM_ensure_looptri(DerivedMesh *dm);
|
||||
void DM_verttri_from_looptri(MVertTri *verttri, const MLoop *mloop, const MLoopTri *looptri, int looptri_num);
|
||||
|
||||
void DM_update_tessface_data(DerivedMesh *dm);
|
||||
void DM_generate_tangent_tessface_data(DerivedMesh *dm, bool generate);
|
||||
|
||||
@@ -86,15 +86,15 @@ typedef struct ClothSolverResult {
|
||||
typedef struct Cloth {
|
||||
struct ClothVertex *verts; /* The vertices that represent this cloth. */
|
||||
struct LinkNode *springs; /* The springs connecting the mesh. */
|
||||
unsigned int numverts; /* The number of verts == m * n. */
|
||||
unsigned int numsprings; /* The count of springs. */
|
||||
unsigned int numfaces;
|
||||
unsigned int mvert_num; /* The number of verts == m * n. */
|
||||
unsigned int tri_num;
|
||||
unsigned char old_solver_type; /* unused, only 1 solver here */
|
||||
unsigned char pad2;
|
||||
short pad3;
|
||||
struct BVHTree *bvhtree; /* collision tree for this cloth object */
|
||||
struct BVHTree *bvhselftree; /* collision tree for this cloth object */
|
||||
struct MFace *mfaces;
|
||||
struct MVertTri *tri;
|
||||
struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */
|
||||
struct EdgeSet *edgeset; /* used for selfcollisions */
|
||||
int last_frame, pad4;
|
||||
@@ -233,8 +233,8 @@ void clothModifier_do (struct ClothModifierData *clmd, struct Scene *scene, stru
|
||||
int cloth_uses_vgroup(struct ClothModifierData *clmd);
|
||||
|
||||
// needed for collision.c
|
||||
void bvhtree_update_from_cloth (struct ClothModifierData *clmd, int moving );
|
||||
void bvhselftree_update_from_cloth (struct ClothModifierData *clmd, int moving );
|
||||
void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
|
||||
void bvhselftree_update_from_cloth(struct ClothModifierData *clmd, bool moving);
|
||||
|
||||
// needed for button_object.c
|
||||
void cloth_clear_cache (struct Object *ob, struct ClothModifierData *clmd, float framenr );
|
||||
|
||||
@@ -49,6 +49,7 @@ struct MFace;
|
||||
struct MVert;
|
||||
struct Object;
|
||||
struct Scene;
|
||||
struct MVertTri;
|
||||
|
||||
////////////////////////////////////////
|
||||
// used for collisions in collision.c
|
||||
@@ -124,8 +125,15 @@ FaceCollPair;
|
||||
// used in modifier.c from collision.c
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
BVHTree *bvhtree_build_from_mvert(struct MFace *mfaces, unsigned int numfaces, struct MVert *x, unsigned int numverts, float epsilon);
|
||||
void bvhtree_update_from_mvert(BVHTree *bvhtree, struct MFace *faces, int numfaces, struct MVert *x, struct MVert *xnew, int numverts, int moving);
|
||||
BVHTree *bvhtree_build_from_mvert(
|
||||
const struct MVert *mvert,
|
||||
const struct MVertTri *tri, int tri_num,
|
||||
float epsilon);
|
||||
void bvhtree_update_from_mvert(
|
||||
BVHTree *bvhtree,
|
||||
const struct MVert *mvert, const struct MVert *mvert_moving,
|
||||
const struct MVertTri *tri, int tri_num,
|
||||
bool moving);
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ typedef struct ParticleBillboardData {
|
||||
|
||||
typedef struct ParticleCollisionElement {
|
||||
/* pointers to original data */
|
||||
float *x[4], *v[4];
|
||||
float *x[3], *v[3];
|
||||
|
||||
/* values interpolated from original data*/
|
||||
float x0[3], x1[3], x2[3], p[3];
|
||||
|
||||
@@ -493,6 +493,16 @@ void DM_ensure_looptri(DerivedMesh *dm)
|
||||
}
|
||||
}
|
||||
|
||||
void DM_verttri_from_looptri(MVertTri *verttri, const MLoop *mloop, const MLoopTri *looptri, int looptri_num)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < looptri_num; i++) {
|
||||
verttri[i].tri[0] = mloop[looptri[i].tri[0]].v;
|
||||
verttri[i].tri[1] = mloop[looptri[i].tri[1]].v;
|
||||
verttri[i].tri[2] = mloop[looptri[i].tri[2]].v;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update tessface CD data from loop/poly ones. Needed when not retessellating after modstack evaluation. */
|
||||
/* NOTE: Assumes dm has valid tessellated data! */
|
||||
void DM_update_tessface_data(DerivedMesh *dm)
|
||||
|
||||
@@ -137,7 +137,6 @@ static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float eps
|
||||
BVHTree *bvhtree;
|
||||
Cloth *cloth;
|
||||
ClothVertex *verts;
|
||||
float co[12];
|
||||
|
||||
if (!clmd)
|
||||
return NULL;
|
||||
@@ -149,21 +148,22 @@ static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float eps
|
||||
|
||||
verts = cloth->verts;
|
||||
|
||||
// in the moment, return zero if no faces there
|
||||
if (!cloth->numverts)
|
||||
/* in the moment, return zero if no faces there */
|
||||
if (!cloth->mvert_num)
|
||||
return NULL;
|
||||
|
||||
// create quadtree with k=26
|
||||
bvhtree = BLI_bvhtree_new(cloth->numverts, epsilon, 4, 6);
|
||||
/* create quadtree with k=26 */
|
||||
bvhtree = BLI_bvhtree_new(cloth->mvert_num, epsilon, 4, 6);
|
||||
|
||||
// fill tree
|
||||
for (i = 0; i < cloth->numverts; i++, verts++) {
|
||||
copy_v3_v3(&co[0*3], verts->xold);
|
||||
/* fill tree */
|
||||
for (i = 0; i < cloth->mvert_num; i++, verts++) {
|
||||
const float *co;
|
||||
co = verts->xold;
|
||||
|
||||
BLI_bvhtree_insert(bvhtree, i, co, 1);
|
||||
}
|
||||
|
||||
// balance tree
|
||||
/* balance tree */
|
||||
BLI_bvhtree_balance(bvhtree);
|
||||
|
||||
return bvhtree;
|
||||
@@ -175,8 +175,7 @@ static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon
|
||||
BVHTree *bvhtree;
|
||||
Cloth *cloth;
|
||||
ClothVertex *verts;
|
||||
MFace *mfaces;
|
||||
float co[12];
|
||||
const MVertTri *vt;
|
||||
|
||||
if (!clmd)
|
||||
return NULL;
|
||||
@@ -187,25 +186,24 @@ static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon
|
||||
return NULL;
|
||||
|
||||
verts = cloth->verts;
|
||||
mfaces = cloth->mfaces;
|
||||
vt = cloth->tri;
|
||||
|
||||
/* in the moment, return zero if no faces there */
|
||||
if (!cloth->numfaces)
|
||||
if (!cloth->tri_num)
|
||||
return NULL;
|
||||
|
||||
/* create quadtree with k=26 */
|
||||
bvhtree = BLI_bvhtree_new(cloth->numfaces, epsilon, 4, 26);
|
||||
bvhtree = BLI_bvhtree_new(cloth->tri_num, epsilon, 4, 26);
|
||||
|
||||
/* fill tree */
|
||||
for (i = 0; i < cloth->numfaces; i++, mfaces++) {
|
||||
copy_v3_v3(&co[0*3], verts[mfaces->v1].xold);
|
||||
copy_v3_v3(&co[1*3], verts[mfaces->v2].xold);
|
||||
copy_v3_v3(&co[2*3], verts[mfaces->v3].xold);
|
||||
for (i = 0; i < cloth->tri_num; i++, vt++) {
|
||||
float co[3][3];
|
||||
|
||||
if (mfaces->v4)
|
||||
copy_v3_v3(&co[3*3], verts[mfaces->v4].xold);
|
||||
copy_v3_v3(co[0], verts[vt->tri[0]].xold);
|
||||
copy_v3_v3(co[1], verts[vt->tri[1]].xold);
|
||||
copy_v3_v3(co[2], verts[vt->tri[2]].xold);
|
||||
|
||||
BLI_bvhtree_insert(bvhtree, i, co, (mfaces->v4 ? 4 : 3));
|
||||
BLI_bvhtree_insert(bvhtree, i, co[0], 3);
|
||||
}
|
||||
|
||||
/* balance tree */
|
||||
@@ -214,90 +212,87 @@ static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon
|
||||
return bvhtree;
|
||||
}
|
||||
|
||||
void bvhtree_update_from_cloth(ClothModifierData *clmd, int moving)
|
||||
void bvhtree_update_from_cloth(ClothModifierData *clmd, bool moving)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
BVHTree *bvhtree = cloth->bvhtree;
|
||||
ClothVertex *verts = cloth->verts;
|
||||
MFace *mfaces;
|
||||
float co[12], co_moving[12];
|
||||
bool ret = false;
|
||||
const MVertTri *vt;
|
||||
|
||||
if (!bvhtree)
|
||||
return;
|
||||
|
||||
mfaces = cloth->mfaces;
|
||||
vt = cloth->tri;
|
||||
|
||||
// update vertex position in bvh tree
|
||||
if (verts && mfaces) {
|
||||
for (i = 0; i < cloth->numfaces; i++, mfaces++) {
|
||||
copy_v3_v3(&co[0*3], verts[mfaces->v1].txold);
|
||||
copy_v3_v3(&co[1*3], verts[mfaces->v2].txold);
|
||||
copy_v3_v3(&co[2*3], verts[mfaces->v3].txold);
|
||||
|
||||
if (mfaces->v4)
|
||||
copy_v3_v3(&co[3*3], verts[mfaces->v4].txold);
|
||||
|
||||
// copy new locations into array
|
||||
/* update vertex position in bvh tree */
|
||||
if (verts && vt) {
|
||||
for (i = 0; i < cloth->tri_num; i++, vt++) {
|
||||
float co[3][3], co_moving[3][3];
|
||||
bool ret;
|
||||
|
||||
copy_v3_v3(co[0], verts[vt->tri[0]].txold);
|
||||
copy_v3_v3(co[1], verts[vt->tri[1]].txold);
|
||||
copy_v3_v3(co[2], verts[vt->tri[2]].txold);
|
||||
|
||||
/* copy new locations into array */
|
||||
if (moving) {
|
||||
// update moving positions
|
||||
copy_v3_v3(&co_moving[0*3], verts[mfaces->v1].tx);
|
||||
copy_v3_v3(&co_moving[1*3], verts[mfaces->v2].tx);
|
||||
copy_v3_v3(&co_moving[2*3], verts[mfaces->v3].tx);
|
||||
|
||||
if (mfaces->v4)
|
||||
copy_v3_v3(&co_moving[3*3], verts[mfaces->v4].tx);
|
||||
|
||||
ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, (mfaces->v4 ? 4 : 3));
|
||||
/* update moving positions */
|
||||
copy_v3_v3(co_moving[0], verts[vt->tri[0]].tx);
|
||||
copy_v3_v3(co_moving[1], verts[vt->tri[1]].tx);
|
||||
copy_v3_v3(co_moving[2], verts[vt->tri[2]].tx);
|
||||
|
||||
ret = BLI_bvhtree_update_node(bvhtree, i, co[0], co_moving[0], 3);
|
||||
}
|
||||
else {
|
||||
ret = BLI_bvhtree_update_node(bvhtree, i, co, NULL, (mfaces->v4 ? 4 : 3));
|
||||
ret = BLI_bvhtree_update_node(bvhtree, i, co[0], NULL, 3);
|
||||
}
|
||||
|
||||
// check if tree is already full
|
||||
if (!ret)
|
||||
/* check if tree is already full */
|
||||
if (ret == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_bvhtree_update_tree(bvhtree);
|
||||
}
|
||||
}
|
||||
|
||||
void bvhselftree_update_from_cloth(ClothModifierData *clmd, int moving)
|
||||
void bvhselftree_update_from_cloth(ClothModifierData *clmd, bool moving)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
BVHTree *bvhtree = cloth->bvhselftree;
|
||||
ClothVertex *verts = cloth->verts;
|
||||
MFace *mfaces;
|
||||
float co[12], co_moving[12];
|
||||
int ret = 0;
|
||||
const MVertTri *vt;
|
||||
|
||||
if (!bvhtree)
|
||||
return;
|
||||
|
||||
mfaces = cloth->mfaces;
|
||||
|
||||
// update vertex position in bvh tree
|
||||
if (verts && mfaces) {
|
||||
for (i = 0; i < cloth->numverts; i++, verts++) {
|
||||
copy_v3_v3(&co[0*3], verts->txold);
|
||||
vt = cloth->tri;
|
||||
|
||||
// copy new locations into array
|
||||
/* update vertex position in bvh tree */
|
||||
if (verts && vt) {
|
||||
for (i = 0; i < cloth->mvert_num; i++, verts++) {
|
||||
const float *co, *co_moving;
|
||||
bool ret;
|
||||
|
||||
co = verts->txold;
|
||||
|
||||
/* copy new locations into array */
|
||||
if (moving) {
|
||||
// update moving positions
|
||||
copy_v3_v3(&co_moving[0*3], verts->tx);
|
||||
|
||||
/* update moving positions */
|
||||
co_moving = verts->tx;
|
||||
ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, 1);
|
||||
}
|
||||
else {
|
||||
ret = BLI_bvhtree_update_node(bvhtree, i, co, NULL, 1);
|
||||
}
|
||||
|
||||
// check if tree is already full
|
||||
if (!ret)
|
||||
/* check if tree is already full */
|
||||
if (ret == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_bvhtree_update_tree(bvhtree);
|
||||
@@ -360,7 +355,7 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
|
||||
mvert = result->getVertArray(result);
|
||||
|
||||
/* force any pinned verts to their constrained location. */
|
||||
for (i = 0; i < clmd->clothObject->numverts; i++, verts++) {
|
||||
for (i = 0; i < clmd->clothObject->mvert_num; i++, verts++) {
|
||||
/* save the previous position. */
|
||||
copy_v3_v3(verts->xold, verts->xconst);
|
||||
copy_v3_v3(verts->txold, verts->x);
|
||||
@@ -462,7 +457,7 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
|
||||
BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale);
|
||||
clmd->sim_parms->timescale= timescale;
|
||||
|
||||
if (clmd->sim_parms->reset || (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->numverts)) {
|
||||
if (clmd->sim_parms->reset || (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->mvert_num)) {
|
||||
clmd->sim_parms->reset = 0;
|
||||
cache->flag |= PTCACHE_OUTDATED;
|
||||
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
|
||||
@@ -562,7 +557,7 @@ void cloth_free_modifier(ClothModifierData *clmd )
|
||||
MEM_freeN ( cloth->verts );
|
||||
|
||||
cloth->verts = NULL;
|
||||
cloth->numverts = 0;
|
||||
cloth->mvert_num = 0;
|
||||
|
||||
// Free the springs.
|
||||
if ( cloth->springs != NULL ) {
|
||||
@@ -589,9 +584,9 @@ void cloth_free_modifier(ClothModifierData *clmd )
|
||||
BLI_bvhtree_free ( cloth->bvhselftree );
|
||||
|
||||
// we save our faces for collision objects
|
||||
if ( cloth->mfaces )
|
||||
MEM_freeN ( cloth->mfaces );
|
||||
|
||||
if (cloth->tri)
|
||||
MEM_freeN(cloth->tri);
|
||||
|
||||
if (cloth->edgeset)
|
||||
BLI_edgeset_free(cloth->edgeset);
|
||||
|
||||
@@ -628,7 +623,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd )
|
||||
MEM_freeN ( cloth->verts );
|
||||
|
||||
cloth->verts = NULL;
|
||||
cloth->numverts = 0;
|
||||
cloth->mvert_num = 0;
|
||||
|
||||
// Free the springs.
|
||||
if ( cloth->springs != NULL ) {
|
||||
@@ -655,8 +650,8 @@ void cloth_free_modifier_extern(ClothModifierData *clmd )
|
||||
BLI_bvhtree_free ( cloth->bvhselftree );
|
||||
|
||||
// we save our faces for collision objects
|
||||
if ( cloth->mfaces )
|
||||
MEM_freeN ( cloth->mfaces );
|
||||
if (cloth->tri)
|
||||
MEM_freeN(cloth->tri);
|
||||
|
||||
if (cloth->edgeset)
|
||||
BLI_edgeset_free(cloth->edgeset);
|
||||
@@ -690,7 +685,7 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*verte
|
||||
/* inverse matrix is not uptodate... */
|
||||
invert_m4_m4(ob->imat, ob->obmat);
|
||||
|
||||
for (i = 0; i < cloth->numverts; i++) {
|
||||
for (i = 0; i < cloth->mvert_num; i++) {
|
||||
copy_v3_v3 (vertexCos[i], cloth->verts[i].x);
|
||||
mul_m4_v3(ob->imat, vertexCos[i]); /* cloth is in global coords */
|
||||
}
|
||||
@@ -721,7 +716,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
|
||||
int j = 0;
|
||||
MDeformVert *dvert = NULL;
|
||||
Cloth *clothObj = NULL;
|
||||
int numverts;
|
||||
int mvert_num;
|
||||
/* float goalfac = 0; */ /* UNUSED */
|
||||
ClothVertex *verts = NULL;
|
||||
|
||||
@@ -729,12 +724,12 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
|
||||
|
||||
clothObj = clmd->clothObject;
|
||||
|
||||
numverts = dm->getNumVerts (dm);
|
||||
mvert_num = dm->getNumVerts(dm);
|
||||
|
||||
verts = clothObj->verts;
|
||||
|
||||
if (cloth_uses_vgroup(clmd)) {
|
||||
for ( i = 0; i < numverts; i++, verts++ ) {
|
||||
for (i = 0; i < mvert_num; i++, verts++) {
|
||||
|
||||
/* Reset Goal values to standard */
|
||||
if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
|
||||
@@ -831,6 +826,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
|
||||
if ( !dm )
|
||||
return 0;
|
||||
|
||||
DM_ensure_looptri(dm);
|
||||
cloth_from_mesh ( clmd, dm );
|
||||
|
||||
// create springs
|
||||
@@ -883,6 +879,9 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
|
||||
// has to be happen before springs are build!
|
||||
cloth_apply_vgroup (clmd, dm);
|
||||
|
||||
/* springs yse MFace currently */
|
||||
DM_ensure_tessface(dm);
|
||||
|
||||
if ( !cloth_build_springs ( clmd, dm ) ) {
|
||||
cloth_free_modifier ( clmd );
|
||||
modifier_setError(&(clmd->modifier), "Cannot build springs");
|
||||
@@ -915,32 +914,31 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
|
||||
|
||||
static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm )
|
||||
{
|
||||
unsigned int numverts = dm->getNumVerts (dm);
|
||||
unsigned int numfaces = dm->getNumTessFaces (dm);
|
||||
MFace *mface = dm->getTessFaceArray(dm);
|
||||
unsigned int i = 0;
|
||||
const MLoop *mloop = dm->getLoopArray(dm);
|
||||
const MLoopTri *looptri = dm->getLoopTriArray(dm);
|
||||
const unsigned int mvert_num = dm->getNumVerts(dm);
|
||||
const unsigned int looptri_num = dm->getNumLoopTri(dm);
|
||||
|
||||
/* Allocate our vertices. */
|
||||
clmd->clothObject->numverts = numverts;
|
||||
clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" );
|
||||
if ( clmd->clothObject->verts == NULL ) {
|
||||
cloth_free_modifier ( clmd );
|
||||
clmd->clothObject->mvert_num = mvert_num;
|
||||
clmd->clothObject->verts = MEM_callocN(sizeof(ClothVertex) * clmd->clothObject->mvert_num, "clothVertex");
|
||||
if (clmd->clothObject->verts == NULL) {
|
||||
cloth_free_modifier(clmd);
|
||||
modifier_setError(&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts");
|
||||
printf("cloth_free_modifier clmd->clothObject->verts\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// save face information
|
||||
clmd->clothObject->numfaces = numfaces;
|
||||
clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" );
|
||||
if ( clmd->clothObject->mfaces == NULL ) {
|
||||
cloth_free_modifier ( clmd );
|
||||
modifier_setError(&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces");
|
||||
printf("cloth_free_modifier clmd->clothObject->mfaces\n");
|
||||
/* save face information */
|
||||
clmd->clothObject->tri_num = looptri_num;
|
||||
clmd->clothObject->tri = MEM_mallocN(sizeof(MVertTri) * looptri_num, "clothLoopTris");
|
||||
if (clmd->clothObject->tri == NULL) {
|
||||
cloth_free_modifier(clmd);
|
||||
modifier_setError(&(clmd->modifier), "Out of memory on allocating clmd->clothObject->looptri");
|
||||
printf("cloth_free_modifier clmd->clothObject->looptri\n");
|
||||
return;
|
||||
}
|
||||
for ( i = 0; i < numfaces; i++ )
|
||||
memcpy ( &clmd->clothObject->mfaces[i], &mface[i], sizeof ( MFace ) );
|
||||
DM_verttri_from_looptri(clmd->clothObject->tri, mloop, looptri, looptri_num);
|
||||
|
||||
/* Free the springs since they can't be correct if the vertices
|
||||
* changed.
|
||||
@@ -997,11 +995,11 @@ int cloth_add_spring(ClothModifierData *clmd, unsigned int indexA, unsigned int
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cloth_free_edgelist(LinkNodePair *edgelist, unsigned int numverts)
|
||||
static void cloth_free_edgelist(LinkNodePair *edgelist, unsigned int mvert_num)
|
||||
{
|
||||
if (edgelist) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
BLI_linklist_free(edgelist[i].list, NULL);
|
||||
}
|
||||
|
||||
@@ -1024,7 +1022,7 @@ static void cloth_free_errorsprings(Cloth *cloth, LinkNodePair *edgelist)
|
||||
cloth->springs = NULL;
|
||||
}
|
||||
|
||||
cloth_free_edgelist(edgelist, cloth->numverts);
|
||||
cloth_free_edgelist(edgelist, cloth->mvert_num);
|
||||
|
||||
if (cloth->edgeset) {
|
||||
BLI_edgeset_free(cloth->edgeset);
|
||||
@@ -1253,7 +1251,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
|
||||
ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
|
||||
unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0;
|
||||
unsigned int i = 0;
|
||||
unsigned int numverts = (unsigned int)dm->getNumVerts (dm);
|
||||
unsigned int mvert_num = (unsigned int)dm->getNumVerts(dm);
|
||||
unsigned int numedges = (unsigned int)dm->getNumEdges (dm);
|
||||
unsigned int numfaces = (unsigned int)dm->getNumTessFaces (dm);
|
||||
float shrink_factor;
|
||||
@@ -1276,7 +1274,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
|
||||
cloth->springs = NULL;
|
||||
cloth->edgeset = NULL;
|
||||
|
||||
edgelist = MEM_callocN(sizeof(*edgelist) * numverts, "cloth_edgelist_alloc" );
|
||||
edgelist = MEM_callocN(sizeof(*edgelist) * mvert_num, "cloth_edgelist_alloc" );
|
||||
|
||||
if (!edgelist)
|
||||
return 0;
|
||||
@@ -1321,7 +1319,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
|
||||
if (struct_springs > 0)
|
||||
clmd->sim_parms->avg_spring_len /= struct_springs;
|
||||
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49f / ((float)cloth->verts[i].spring_count);
|
||||
}
|
||||
|
||||
@@ -1511,7 +1509,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
|
||||
|
||||
cloth->numsprings = struct_springs + shear_springs + bend_springs;
|
||||
|
||||
cloth_free_edgelist(edgelist, numverts);
|
||||
cloth_free_edgelist(edgelist, mvert_num);
|
||||
|
||||
#if 0
|
||||
if (G.debug_value > 0)
|
||||
|
||||
@@ -71,82 +71,92 @@ void collision_move_object(CollisionModifierData *collmd, float step, float prev
|
||||
float tv[3] = {0, 0, 0};
|
||||
unsigned int i = 0;
|
||||
|
||||
for ( i = 0; i < collmd->numverts; i++ ) {
|
||||
for (i = 0; i < collmd->mvert_num; i++) {
|
||||
sub_v3_v3v3(tv, collmd->xnew[i].co, collmd->x[i].co);
|
||||
VECADDS(collmd->current_x[i].co, collmd->x[i].co, tv, prevstep);
|
||||
VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step);
|
||||
sub_v3_v3v3(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co);
|
||||
}
|
||||
|
||||
bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 );
|
||||
bvhtree_update_from_mvert(
|
||||
collmd->bvhtree, collmd->current_x, collmd->current_xnew,
|
||||
collmd->tri, collmd->tri_num, true);
|
||||
}
|
||||
|
||||
BVHTree *bvhtree_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int UNUSED(numverts), float epsilon )
|
||||
BVHTree *bvhtree_build_from_mvert(
|
||||
const MVert *mvert,
|
||||
const struct MVertTri *tri, int tri_num,
|
||||
float epsilon)
|
||||
{
|
||||
BVHTree *tree;
|
||||
float co[12];
|
||||
unsigned int i;
|
||||
MFace *tface = mfaces;
|
||||
const MVertTri *vt;
|
||||
int i;
|
||||
|
||||
tree = BLI_bvhtree_new ( numfaces*2, epsilon, 4, 26 );
|
||||
tree = BLI_bvhtree_new(tri_num, epsilon, 4, 26);
|
||||
|
||||
// fill tree
|
||||
for ( i = 0; i < numfaces; i++, tface++ ) {
|
||||
copy_v3_v3 ( &co[0*3], x[tface->v1].co );
|
||||
copy_v3_v3 ( &co[1*3], x[tface->v2].co );
|
||||
copy_v3_v3 ( &co[2*3], x[tface->v3].co );
|
||||
if ( tface->v4 )
|
||||
copy_v3_v3 ( &co[3*3], x[tface->v4].co );
|
||||
/* fill tree */
|
||||
for (i = 0, vt = tri; i < tri_num; i++, vt++) {
|
||||
float co[3][3];
|
||||
|
||||
BLI_bvhtree_insert ( tree, i, co, ( mfaces->v4 ? 4 : 3 ) );
|
||||
copy_v3_v3(co[0], mvert[vt->tri[0]].co);
|
||||
copy_v3_v3(co[1], mvert[vt->tri[1]].co);
|
||||
copy_v3_v3(co[2], mvert[vt->tri[2]].co);
|
||||
|
||||
BLI_bvhtree_insert(tree, i, co[0], 3);
|
||||
}
|
||||
|
||||
// balance tree
|
||||
BLI_bvhtree_balance ( tree );
|
||||
/* balance tree */
|
||||
BLI_bvhtree_balance(tree);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
void bvhtree_update_from_mvert(BVHTree *bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int UNUSED(numverts), int moving )
|
||||
void bvhtree_update_from_mvert(
|
||||
BVHTree *bvhtree,
|
||||
const MVert *mvert, const MVert *mvert_moving,
|
||||
const MVertTri *tri, int tri_num,
|
||||
bool moving)
|
||||
{
|
||||
const MVertTri *vt;
|
||||
int i;
|
||||
MFace *mfaces = faces;
|
||||
float co[12], co_moving[12];
|
||||
bool ret = false;
|
||||
|
||||
if ( !bvhtree )
|
||||
if ((bvhtree == NULL) || (mvert == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( x ) {
|
||||
for ( i = 0; i < numfaces; i++, mfaces++ ) {
|
||||
copy_v3_v3 ( &co[0*3], x[mfaces->v1].co );
|
||||
copy_v3_v3 ( &co[1*3], x[mfaces->v2].co );
|
||||
copy_v3_v3 ( &co[2*3], x[mfaces->v3].co );
|
||||
if ( mfaces->v4 )
|
||||
copy_v3_v3 ( &co[3*3], x[mfaces->v4].co );
|
||||
if (mvert_moving == NULL) {
|
||||
moving = false;
|
||||
}
|
||||
|
||||
// copy new locations into array
|
||||
if ( moving && xnew ) {
|
||||
// update moving positions
|
||||
copy_v3_v3 ( &co_moving[0*3], xnew[mfaces->v1].co );
|
||||
copy_v3_v3 ( &co_moving[1*3], xnew[mfaces->v2].co );
|
||||
copy_v3_v3 ( &co_moving[2*3], xnew[mfaces->v3].co );
|
||||
if ( mfaces->v4 )
|
||||
copy_v3_v3 ( &co_moving[3*3], xnew[mfaces->v4].co );
|
||||
for (i = 0, vt = tri; i < tri_num; i++, vt++) {
|
||||
float co[3][3];
|
||||
bool ret;
|
||||
|
||||
ret = BLI_bvhtree_update_node ( bvhtree, i, co, co_moving, ( mfaces->v4 ? 4 : 3 ) );
|
||||
}
|
||||
else {
|
||||
ret = BLI_bvhtree_update_node ( bvhtree, i, co, NULL, ( mfaces->v4 ? 4 : 3 ) );
|
||||
}
|
||||
copy_v3_v3(co[0], mvert[vt->tri[0]].co);
|
||||
copy_v3_v3(co[1], mvert[vt->tri[1]].co);
|
||||
copy_v3_v3(co[2], mvert[vt->tri[2]].co);
|
||||
|
||||
// check if tree is already full
|
||||
if ( !ret )
|
||||
break;
|
||||
/* copy new locations into array */
|
||||
if (moving) {
|
||||
float co_moving[3][3];
|
||||
/* update moving positions */
|
||||
copy_v3_v3(co_moving[0], mvert_moving[vt->tri[0]].co);
|
||||
copy_v3_v3(co_moving[1], mvert_moving[vt->tri[1]].co);
|
||||
copy_v3_v3(co_moving[2], mvert_moving[vt->tri[2]].co);
|
||||
|
||||
ret = BLI_bvhtree_update_node(bvhtree, i, &co[0][0], &co_moving[0][0], 3);
|
||||
}
|
||||
else {
|
||||
ret = BLI_bvhtree_update_node(bvhtree, i, &co[0][0], NULL, 3);
|
||||
}
|
||||
|
||||
BLI_bvhtree_update_tree ( bvhtree );
|
||||
/* check if tree is already full */
|
||||
if (ret == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_bvhtree_update_tree(bvhtree);
|
||||
}
|
||||
|
||||
/***********************************
|
||||
@@ -380,80 +390,29 @@ static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2,
|
||||
ClothModifierData *clmd = (ClothModifierData *)md1;
|
||||
CollisionModifierData *collmd = (CollisionModifierData *) md2;
|
||||
/* Cloth *cloth = clmd->clothObject; */ /* UNUSED */
|
||||
MFace *face1=NULL, *face2 = NULL;
|
||||
const MVertTri *tri_a, *tri_b;
|
||||
#ifdef WITH_BULLET
|
||||
ClothVertex *verts1 = clmd->clothObject->verts;
|
||||
#endif
|
||||
double distance = 0;
|
||||
float epsilon1 = clmd->coll_parms->epsilon;
|
||||
float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
|
||||
int i;
|
||||
|
||||
face1 = & ( clmd->clothObject->mfaces[overlap->indexA] );
|
||||
face2 = & ( collmd->mfaces[overlap->indexB] );
|
||||
tri_a = &clmd->clothObject->tri[overlap->indexA];
|
||||
tri_b = &collmd->tri[overlap->indexB];
|
||||
|
||||
// check all 4 possible collisions
|
||||
for ( i = 0; i < 4; i++ ) {
|
||||
if ( i == 0 ) {
|
||||
// fill faceA
|
||||
collpair->ap1 = face1->v1;
|
||||
collpair->ap2 = face1->v2;
|
||||
collpair->ap3 = face1->v3;
|
||||
/* fill face_a */
|
||||
collpair->ap1 = tri_a->tri[0];
|
||||
collpair->ap2 = tri_a->tri[1];
|
||||
collpair->ap3 = tri_a->tri[2];
|
||||
|
||||
// fill faceB
|
||||
collpair->bp1 = face2->v1;
|
||||
collpair->bp2 = face2->v2;
|
||||
collpair->bp3 = face2->v3;
|
||||
}
|
||||
else if ( i == 1 ) {
|
||||
if ( face1->v4 ) {
|
||||
// fill faceA
|
||||
collpair->ap1 = face1->v1;
|
||||
collpair->ap2 = face1->v3;
|
||||
collpair->ap3 = face1->v4;
|
||||
/* fill face_b */
|
||||
collpair->bp1 = tri_b->tri[0];
|
||||
collpair->bp2 = tri_b->tri[1];
|
||||
collpair->bp3 = tri_b->tri[2];
|
||||
|
||||
// fill faceB
|
||||
collpair->bp1 = face2->v1;
|
||||
collpair->bp2 = face2->v2;
|
||||
collpair->bp3 = face2->v3;
|
||||
}
|
||||
else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if ( i == 2 ) {
|
||||
if ( face2->v4 ) {
|
||||
// fill faceA
|
||||
collpair->ap1 = face1->v1;
|
||||
collpair->ap2 = face1->v2;
|
||||
collpair->ap3 = face1->v3;
|
||||
{
|
||||
|
||||
// fill faceB
|
||||
collpair->bp1 = face2->v1;
|
||||
collpair->bp2 = face2->v4;
|
||||
collpair->bp3 = face2->v3;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( i == 3 ) {
|
||||
if ( face1->v4 && face2->v4 ) {
|
||||
// fill faceA
|
||||
collpair->ap1 = face1->v1;
|
||||
collpair->ap2 = face1->v3;
|
||||
collpair->ap3 = face1->v4;
|
||||
|
||||
// fill faceB
|
||||
collpair->bp1 = face2->v1;
|
||||
collpair->bp2 = face2->v3;
|
||||
collpair->bp3 = face2->v4;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_BULLET
|
||||
// calc distance + normal
|
||||
distance = plNearestPoints (
|
||||
@@ -662,12 +621,12 @@ static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, Collis
|
||||
static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
|
||||
{
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
int i=0, j = 0, /*numfaces = 0, */ numverts = 0;
|
||||
int i=0, j = 0, /*numfaces = 0, */ mvert_num = 0;
|
||||
ClothVertex *verts = NULL;
|
||||
int ret = 0;
|
||||
int result = 0;
|
||||
|
||||
numverts = clmd->clothObject->numverts;
|
||||
mvert_num = clmd->clothObject->mvert_num;
|
||||
verts = cloth->verts;
|
||||
|
||||
// process all collisions (calculate impulses, TODO: also repulses if distance too short)
|
||||
@@ -680,7 +639,7 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision
|
||||
|
||||
// apply impulses in parallel
|
||||
if (result) {
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
// calculate "velocities" (just xnew = xold + v; no dt in v)
|
||||
if (verts[i].impulse_count) {
|
||||
// VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
|
||||
@@ -706,7 +665,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
|
||||
{
|
||||
Cloth *cloth= clmd->clothObject;
|
||||
BVHTree *cloth_bvh= cloth->bvhtree;
|
||||
unsigned int i=0, /* numfaces = 0, */ /* UNUSED */ numverts = 0, k, l, j;
|
||||
unsigned int i=0, /* numfaces = 0, */ /* UNUSED */ mvert_num = 0, k, l, j;
|
||||
int rounds = 0; // result counts applied collisions; ic is for debug output;
|
||||
ClothVertex *verts = NULL;
|
||||
int ret = 0, ret2 = 0;
|
||||
@@ -718,7 +677,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
|
||||
|
||||
verts = cloth->verts;
|
||||
/* numfaces = cloth->numfaces; */ /* UNUSED */
|
||||
numverts = cloth->numverts;
|
||||
mvert_num = cloth->mvert_num;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// static collisions
|
||||
@@ -794,8 +753,8 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
|
||||
// this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// verts come from clmd
|
||||
for ( i = 0; i < numverts; i++ ) {
|
||||
/* verts come from clmd */
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) {
|
||||
if ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) {
|
||||
continue;
|
||||
@@ -820,7 +779,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
|
||||
verts = cloth->verts; // needed for openMP
|
||||
|
||||
/* numfaces = cloth->numfaces; */ /* UNUSED */
|
||||
numverts = cloth->numverts;
|
||||
mvert_num = cloth->mvert_num;
|
||||
|
||||
verts = cloth->verts;
|
||||
|
||||
@@ -898,8 +857,8 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
|
||||
////////////////////////////////////////////////////////////
|
||||
// SELFCOLLISIONS: update velocities
|
||||
////////////////////////////////////////////////////////////
|
||||
if ( ret2 ) {
|
||||
for ( i = 0; i < cloth->numverts; i++ ) {
|
||||
if (ret2) {
|
||||
for (i = 0; i < cloth->mvert_num; i++) {
|
||||
if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) ) {
|
||||
sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
|
||||
}
|
||||
@@ -1104,10 +1063,11 @@ BLI_INLINE bool cloth_point_face_collision_params(const float p1[3], const float
|
||||
#endif
|
||||
}
|
||||
|
||||
static CollPair *cloth_point_collpair(float p1[3], float p2[3], MVert *mverts, int bp1, int bp2, int bp3,
|
||||
int index_cloth, int index_coll, float epsilon, CollPair *collpair)
|
||||
static CollPair *cloth_point_collpair(
|
||||
float p1[3], float p2[3], const MVert *mverts, int bp1, int bp2, int bp3,
|
||||
int index_cloth, int index_coll, float epsilon, CollPair *collpair)
|
||||
{
|
||||
float *co1 = mverts[bp1].co, *co2 = mverts[bp2].co, *co3 = mverts[bp3].co;
|
||||
const float *co1 = mverts[bp1].co, *co2 = mverts[bp2].co, *co3 = mverts[bp3].co;
|
||||
float lambda /*, distance1 */, distance2;
|
||||
float facenor[3], v1p1[3], v1p2[3];
|
||||
float w[4];
|
||||
@@ -1149,22 +1109,25 @@ static CollPair *cloth_point_collpair(float p1[3], float p2[3], MVert *mverts, i
|
||||
}
|
||||
|
||||
//Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned
|
||||
static CollPair* cloth_point_collision(ModifierData *md1, ModifierData *md2,
|
||||
BVHTreeOverlap *overlap, float epsilon, CollPair *collpair, float UNUSED(dt))
|
||||
static CollPair *cloth_point_collision(
|
||||
ModifierData *md1, ModifierData *md2,
|
||||
BVHTreeOverlap *overlap, float epsilon, CollPair *collpair, float UNUSED(dt))
|
||||
{
|
||||
ClothModifierData *clmd = (ClothModifierData *)md1;
|
||||
CollisionModifierData *collmd = (CollisionModifierData *) md2;
|
||||
/* Cloth *cloth = clmd->clothObject; */ /* UNUSED */
|
||||
ClothVertex *vert = NULL;
|
||||
MFace *face = NULL;
|
||||
MVert *mverts = collmd->current_x;
|
||||
const MVertTri *vt;
|
||||
const MVert *mverts = collmd->current_x;
|
||||
|
||||
vert = &clmd->clothObject->verts[overlap->indexA];
|
||||
face = &collmd->mfaces[overlap->indexB];
|
||||
vt = &collmd->tri[overlap->indexB];
|
||||
|
||||
collpair = cloth_point_collpair(vert->tx, vert->x, mverts, face->v1, face->v2, face->v3, overlap->indexA, overlap->indexB, epsilon, collpair);
|
||||
if (face->v4)
|
||||
collpair = cloth_point_collpair(vert->tx, vert->x, mverts, face->v3, face->v4, face->v1, overlap->indexA, overlap->indexB, epsilon, collpair);
|
||||
collpair = cloth_point_collpair(
|
||||
vert->tx, vert->x, mverts,
|
||||
vt->tri[0], vt->tri[1], vt->tri[2],
|
||||
overlap->indexA, overlap->indexB,
|
||||
epsilon, collpair);
|
||||
|
||||
return collpair;
|
||||
}
|
||||
@@ -1189,7 +1152,7 @@ static int cloth_points_objcollisions_resolve(ClothModifierData * clmd, Collisio
|
||||
CollPair *collisions, CollPair *collisions_index, float dt)
|
||||
{
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
int i=0, numverts = clmd->clothObject->numverts;
|
||||
int i = 0, mvert_num = clmd->clothObject->mvert_num;
|
||||
ClothVertex *verts = cloth->verts;
|
||||
int ret = 0;
|
||||
|
||||
@@ -1199,7 +1162,7 @@ static int cloth_points_objcollisions_resolve(ClothModifierData * clmd, Collisio
|
||||
|
||||
// apply impulses in parallel
|
||||
if (result) {
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
// calculate "velocities" (just xnew = xold + v; no dt in v)
|
||||
if (verts[i].impulse_count) {
|
||||
// VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
|
||||
@@ -1223,29 +1186,29 @@ int cloth_points_objcollision(Object *ob, ClothModifierData *clmd, float step, f
|
||||
BVHTree *cloth_bvh;
|
||||
int rounds = 0; // result counts applied collisions; ic is for debug output;
|
||||
float round_dt = dt / (float)clmd->coll_parms->loop_count;
|
||||
unsigned int i=0, numverts = 0;
|
||||
unsigned int i = 0, mvert_num = 0;
|
||||
ClothVertex *verts = NULL;
|
||||
int ret = 0, ret2 = 0;
|
||||
Object **collobjs = NULL;
|
||||
unsigned int numcollobj = 0;
|
||||
|
||||
verts = cloth->verts;
|
||||
numverts = cloth->numverts;
|
||||
mvert_num = cloth->mvert_num;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// static collisions
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// create temporary cloth points bvh
|
||||
cloth_bvh = BLI_bvhtree_new(numverts, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel), 4, 6);
|
||||
cloth_bvh = BLI_bvhtree_new(mvert_num, max_ff(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel), 4, 6);
|
||||
/* fill tree */
|
||||
for (i = 0; i < numverts; i++) {
|
||||
float co[6];
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
float co[2][3];
|
||||
|
||||
copy_v3_v3(&co[0*3], verts[i].x);
|
||||
copy_v3_v3(&co[1*3], verts[i].tx);
|
||||
copy_v3_v3(co[0], verts[i].x);
|
||||
copy_v3_v3(co[1], verts[i].tx);
|
||||
|
||||
BLI_bvhtree_insert(cloth_bvh, i, co, 2);
|
||||
BLI_bvhtree_insert(cloth_bvh, i, co[0], 2);
|
||||
}
|
||||
/* balance tree */
|
||||
BLI_bvhtree_balance(cloth_bvh);
|
||||
@@ -1318,7 +1281,7 @@ int cloth_points_objcollision(Object *ob, ClothModifierData *clmd, float step, f
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// verts come from clmd
|
||||
for ( i = 0; i < numverts; i++ ) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) {
|
||||
if ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) {
|
||||
continue;
|
||||
@@ -1344,7 +1307,7 @@ void cloth_find_point_contacts(Object *ob, ClothModifierData *clmd, float step,
|
||||
{
|
||||
Cloth *cloth= clmd->clothObject;
|
||||
BVHTree *cloth_bvh;
|
||||
unsigned int i=0, numverts = 0;
|
||||
unsigned int i = 0, mvert_num = 0;
|
||||
ClothVertex *verts = NULL;
|
||||
|
||||
ColliderContacts *collider_contacts;
|
||||
@@ -1353,16 +1316,16 @@ void cloth_find_point_contacts(Object *ob, ClothModifierData *clmd, float step,
|
||||
unsigned int numcollobj = 0;
|
||||
|
||||
verts = cloth->verts;
|
||||
numverts = cloth->numverts;
|
||||
mvert_num = cloth->mvert_num;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// static collisions
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// create temporary cloth points bvh
|
||||
cloth_bvh = BLI_bvhtree_new(numverts, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel), 4, 6);
|
||||
cloth_bvh = BLI_bvhtree_new(mvert_num, max_ff(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel), 4, 6);
|
||||
/* fill tree */
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
float co[6];
|
||||
|
||||
copy_v3_v3(&co[0*3], verts[i].x);
|
||||
@@ -1442,7 +1405,7 @@ void cloth_find_point_contacts(Object *ob, ClothModifierData *clmd, float step,
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// verts come from clmd
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) {
|
||||
if (verts [i].flags & CLOTH_VERT_FLAG_PINNED) {
|
||||
continue;
|
||||
|
||||
@@ -2477,10 +2477,6 @@ static int collision_sphere_to_edges(ParticleCollision *col, float radius, Parti
|
||||
int i;
|
||||
|
||||
for (i=0; i<3; i++) {
|
||||
/* in case of a quad, no need to check "edge" that goes through face twice */
|
||||
if ((pce->x[3] && i==2))
|
||||
continue;
|
||||
|
||||
cur = edge+i;
|
||||
cur->x[0] = pce->x[i]; cur->x[1] = pce->x[(i+1)%3];
|
||||
cur->v[0] = pce->v[i]; cur->v[1] = pce->v[(i+1)%3];
|
||||
@@ -2524,10 +2520,6 @@ static int collision_sphere_to_verts(ParticleCollision *col, float radius, Parti
|
||||
int i;
|
||||
|
||||
for (i=0; i<3; i++) {
|
||||
/* in case of quad, only check one vert the first time */
|
||||
if (pce->x[3] && i != 1)
|
||||
continue;
|
||||
|
||||
cur = vert+i;
|
||||
cur->x[0] = pce->x[i];
|
||||
cur->v[0] = pce->v[i];
|
||||
@@ -2555,21 +2547,19 @@ void BKE_psys_collision_neartest_cb(void *userdata, int index, const BVHTreeRay
|
||||
{
|
||||
ParticleCollision *col = (ParticleCollision *) userdata;
|
||||
ParticleCollisionElement pce;
|
||||
MFace *face = col->md->mfaces + index;
|
||||
const MVertTri *vt = &col->md->tri[index];
|
||||
MVert *x = col->md->x;
|
||||
MVert *v = col->md->current_v;
|
||||
float t = hit->dist/col->original_ray_length;
|
||||
int collision = 0;
|
||||
|
||||
pce.x[0] = x[face->v1].co;
|
||||
pce.x[1] = x[face->v2].co;
|
||||
pce.x[2] = x[face->v3].co;
|
||||
pce.x[3] = face->v4 ? x[face->v4].co : NULL;
|
||||
pce.x[0] = x[vt->tri[0]].co;
|
||||
pce.x[1] = x[vt->tri[1]].co;
|
||||
pce.x[2] = x[vt->tri[2]].co;
|
||||
|
||||
pce.v[0] = v[face->v1].co;
|
||||
pce.v[1] = v[face->v2].co;
|
||||
pce.v[2] = v[face->v3].co;
|
||||
pce.v[3] = face->v4 ? v[face->v4].co : NULL;
|
||||
pce.v[0] = v[vt->tri[0]].co;
|
||||
pce.v[1] = v[vt->tri[1]].co;
|
||||
pce.v[2] = v[vt->tri[2]].co;
|
||||
|
||||
pce.tot = 3;
|
||||
pce.inside = 0;
|
||||
@@ -2579,31 +2569,20 @@ void BKE_psys_collision_neartest_cb(void *userdata, int index, const BVHTreeRay
|
||||
if (col->hit == col->current && col->pce.index == index && col->pce.tot == 3)
|
||||
return;
|
||||
|
||||
do {
|
||||
collision = collision_sphere_to_tri(col, ray->radius, &pce, &t);
|
||||
if (col->pce.inside == 0) {
|
||||
collision += collision_sphere_to_edges(col, ray->radius, &pce, &t);
|
||||
collision += collision_sphere_to_verts(col, ray->radius, &pce, &t);
|
||||
}
|
||||
collision = collision_sphere_to_tri(col, ray->radius, &pce, &t);
|
||||
if (col->pce.inside == 0) {
|
||||
collision += collision_sphere_to_edges(col, ray->radius, &pce, &t);
|
||||
collision += collision_sphere_to_verts(col, ray->radius, &pce, &t);
|
||||
}
|
||||
|
||||
if (collision) {
|
||||
hit->dist = col->original_ray_length * t;
|
||||
hit->index = index;
|
||||
|
||||
collision_point_velocity(&col->pce);
|
||||
if (collision) {
|
||||
hit->dist = col->original_ray_length * t;
|
||||
hit->index = index;
|
||||
|
||||
col->hit = col->current;
|
||||
}
|
||||
collision_point_velocity(&col->pce);
|
||||
|
||||
pce.x[1] = pce.x[2];
|
||||
pce.x[2] = pce.x[3];
|
||||
pce.x[3] = NULL;
|
||||
|
||||
pce.v[1] = pce.v[2];
|
||||
pce.v[2] = pce.v[3];
|
||||
pce.v[3] = NULL;
|
||||
|
||||
} while (pce.x[2]);
|
||||
col->hit = col->current;
|
||||
}
|
||||
}
|
||||
static int collision_detect(ParticleData *pa, ParticleCollision *col, BVHTreeRayHit *hit, ListBase *colliders)
|
||||
{
|
||||
|
||||
@@ -543,7 +543,7 @@ static void ptcache_cloth_interpolate(int index, void *cloth_v, void **data, flo
|
||||
static int ptcache_cloth_totpoint(void *cloth_v, int UNUSED(cfra))
|
||||
{
|
||||
ClothModifierData *clmd= cloth_v;
|
||||
return clmd->clothObject ? clmd->clothObject->numverts : 0;
|
||||
return clmd->clothObject ? clmd->clothObject->mvert_num : 0;
|
||||
}
|
||||
|
||||
static void ptcache_cloth_error(void *cloth_v, const char *message)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4894,9 +4894,10 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
||||
collmd->current_xnew = NULL;
|
||||
collmd->current_v = NULL;
|
||||
collmd->time_x = collmd->time_xnew = -1000;
|
||||
collmd->numverts = 0;
|
||||
collmd->mvert_num = 0;
|
||||
collmd->tri_num = 0;
|
||||
collmd->bvhtree = NULL;
|
||||
collmd->mfaces = NULL;
|
||||
collmd->tri = NULL;
|
||||
|
||||
}
|
||||
else if (md->type == eModifierType_Surface) {
|
||||
|
||||
@@ -96,6 +96,12 @@ typedef struct MLoopTri {
|
||||
unsigned int tri[3];
|
||||
unsigned int poly;
|
||||
} MLoopTri;
|
||||
#
|
||||
#
|
||||
typedef struct MVertTri {
|
||||
unsigned int tri[3];
|
||||
} MVertTri;
|
||||
|
||||
|
||||
typedef struct MTexPoly {
|
||||
struct Image *tpage;
|
||||
|
||||
@@ -612,10 +612,10 @@ typedef struct CollisionModifierData {
|
||||
struct MVert *current_x; /* position at the actual inter-frame step */
|
||||
struct MVert *current_v; /* (xnew - x) at the actual inter-frame step */
|
||||
|
||||
struct MFace *mfaces; /* object face data */
|
||||
struct MVertTri *tri;
|
||||
|
||||
unsigned int numverts;
|
||||
unsigned int numfaces;
|
||||
unsigned int mvert_num;
|
||||
unsigned int tri_num;
|
||||
float time_x, time_xnew; /* cfra time of modifier */
|
||||
struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */
|
||||
} CollisionModifierData;
|
||||
|
||||
@@ -58,7 +58,8 @@ static void initData(ModifierData *md)
|
||||
collmd->current_xnew = NULL;
|
||||
collmd->current_v = NULL;
|
||||
collmd->time_x = collmd->time_xnew = -1000;
|
||||
collmd->numverts = 0;
|
||||
collmd->mvert_num = 0;
|
||||
collmd->tri_num = 0;
|
||||
collmd->bvhtree = NULL;
|
||||
}
|
||||
|
||||
@@ -77,10 +78,15 @@ static void freeData(ModifierData *md)
|
||||
MEM_SAFE_FREE(collmd->current_x);
|
||||
MEM_SAFE_FREE(collmd->current_xnew);
|
||||
MEM_SAFE_FREE(collmd->current_v);
|
||||
MEM_SAFE_FREE(collmd->mfaces);
|
||||
|
||||
if (collmd->tri) {
|
||||
MEM_freeN((void *)collmd->tri);
|
||||
collmd->tri = NULL;
|
||||
}
|
||||
|
||||
collmd->time_x = collmd->time_xnew = -1000;
|
||||
collmd->numverts = 0;
|
||||
collmd->mvert_num = 0;
|
||||
collmd->tri_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +116,7 @@ static void deformVerts(ModifierData *md, Object *ob,
|
||||
|
||||
if (dm) {
|
||||
float current_time = 0;
|
||||
unsigned int numverts = 0;
|
||||
unsigned int mvert_num = 0;
|
||||
|
||||
CDDM_apply_vert_coords(dm, vertexCos);
|
||||
CDDM_calc_normals(dm);
|
||||
@@ -120,19 +126,20 @@ static void deformVerts(ModifierData *md, Object *ob,
|
||||
if (G.debug_value > 0)
|
||||
printf("current_time %f, collmd->time_xnew %f\n", current_time, collmd->time_xnew);
|
||||
|
||||
numverts = dm->getNumVerts(dm);
|
||||
mvert_num = dm->getNumVerts(dm);
|
||||
|
||||
if (current_time > collmd->time_xnew) {
|
||||
unsigned int i;
|
||||
|
||||
/* check if mesh has changed */
|
||||
if (collmd->x && (numverts != collmd->numverts))
|
||||
if (collmd->x && (mvert_num != collmd->mvert_num))
|
||||
freeData((ModifierData *)collmd);
|
||||
|
||||
if (collmd->time_xnew == -1000) { /* first time */
|
||||
|
||||
collmd->x = dm->dupVertArray(dm); /* frame start position */
|
||||
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
/* we save global positions */
|
||||
mul_m4_v3(ob->obmat, collmd->x[i].co);
|
||||
}
|
||||
@@ -142,56 +149,75 @@ static void deformVerts(ModifierData *md, Object *ob,
|
||||
collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
|
||||
collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
|
||||
|
||||
collmd->numverts = numverts;
|
||||
collmd->mvert_num = mvert_num;
|
||||
|
||||
DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
|
||||
DM_ensure_looptri(dm);
|
||||
|
||||
collmd->tri_num = dm->getNumLoopTri(dm);
|
||||
{
|
||||
const MLoop *mloop = dm->getLoopArray(dm);
|
||||
const MLoopTri *looptri = dm->getLoopTriArray(dm);
|
||||
MVertTri *tri = MEM_mallocN(sizeof(*tri) * collmd->tri_num, __func__);
|
||||
DM_verttri_from_looptri(tri, mloop, looptri, collmd->tri_num);
|
||||
collmd->tri = tri;
|
||||
}
|
||||
|
||||
collmd->mfaces = dm->dupTessFaceArray(dm);
|
||||
collmd->numfaces = dm->getNumTessFaces(dm);
|
||||
|
||||
/* create bounding box hierarchy */
|
||||
collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sboft);
|
||||
collmd->bvhtree = bvhtree_build_from_mvert(
|
||||
collmd->x,
|
||||
collmd->tri, collmd->tri_num,
|
||||
ob->pd->pdef_sboft);
|
||||
|
||||
collmd->time_x = collmd->time_xnew = current_time;
|
||||
}
|
||||
else if (numverts == collmd->numverts) {
|
||||
else if (mvert_num == collmd->mvert_num) {
|
||||
/* put positions to old positions */
|
||||
tempVert = collmd->x;
|
||||
collmd->x = collmd->xnew;
|
||||
collmd->xnew = tempVert;
|
||||
collmd->time_x = collmd->time_xnew;
|
||||
|
||||
memcpy(collmd->xnew, dm->getVertArray(dm), numverts * sizeof(MVert));
|
||||
memcpy(collmd->xnew, dm->getVertArray(dm), mvert_num * sizeof(MVert));
|
||||
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
/* we save global positions */
|
||||
mul_m4_v3(ob->obmat, collmd->xnew[i].co);
|
||||
}
|
||||
|
||||
memcpy(collmd->current_xnew, collmd->x, numverts * sizeof(MVert));
|
||||
memcpy(collmd->current_x, collmd->x, numverts * sizeof(MVert));
|
||||
memcpy(collmd->current_xnew, collmd->x, mvert_num * sizeof(MVert));
|
||||
memcpy(collmd->current_x, collmd->x, mvert_num * sizeof(MVert));
|
||||
|
||||
/* check if GUI setting has changed for bvh */
|
||||
if (collmd->bvhtree) {
|
||||
if (ob->pd->pdef_sboft != BLI_bvhtree_getepsilon(collmd->bvhtree)) {
|
||||
BLI_bvhtree_free(collmd->bvhtree);
|
||||
collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
|
||||
collmd->bvhtree = bvhtree_build_from_mvert(
|
||||
collmd->current_x,
|
||||
collmd->tri, collmd->tri_num,
|
||||
ob->pd->pdef_sboft);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* happens on file load (ONLY when i decomment changes in readfile.c) */
|
||||
if (!collmd->bvhtree) {
|
||||
collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
|
||||
collmd->bvhtree = bvhtree_build_from_mvert(
|
||||
collmd->current_x,
|
||||
collmd->tri, collmd->tri_num,
|
||||
ob->pd->pdef_sboft);
|
||||
}
|
||||
else {
|
||||
/* recalc static bounding boxes */
|
||||
bvhtree_update_from_mvert(collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1);
|
||||
bvhtree_update_from_mvert(
|
||||
collmd->bvhtree,
|
||||
collmd->current_x, collmd->current_xnew,
|
||||
collmd->tri, collmd->tri_num,
|
||||
true);
|
||||
}
|
||||
|
||||
collmd->time_xnew = current_time;
|
||||
}
|
||||
else if (numverts != collmd->numverts) {
|
||||
else if (mvert_num != collmd->mvert_num) {
|
||||
freeData((ModifierData *)collmd);
|
||||
}
|
||||
|
||||
@@ -200,7 +226,7 @@ static void deformVerts(ModifierData *md, Object *ob,
|
||||
freeData((ModifierData *)collmd);
|
||||
}
|
||||
else {
|
||||
if (numverts != collmd->numverts) {
|
||||
if (mvert_num != collmd->mvert_num) {
|
||||
freeData((ModifierData *)collmd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ typedef enum eMassSpringSolverStatus {
|
||||
|
||||
struct Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings);
|
||||
void BPH_mass_spring_solver_free(struct Implicit_Data *id);
|
||||
int BPH_mass_spring_solver_numvert(struct Implicit_Data *id);
|
||||
|
||||
int BPH_cloth_solver_init(struct Object *ob, struct ClothModifierData *clmd);
|
||||
void BPH_cloth_solver_free(struct ClothModifierData *clmd);
|
||||
|
||||
@@ -88,13 +88,13 @@ int BPH_cloth_solver_init(Object *UNUSED(ob), ClothModifierData *clmd)
|
||||
unsigned int i, nondiag;
|
||||
|
||||
nondiag = cloth_count_nondiag_blocks(cloth);
|
||||
cloth->implicit = id = BPH_mass_spring_solver_create(cloth->numverts, nondiag);
|
||||
cloth->implicit = id = BPH_mass_spring_solver_create(cloth->mvert_num, nondiag);
|
||||
|
||||
for (i = 0; i < cloth->numverts; i++) {
|
||||
for (i = 0; i < cloth->mvert_num; i++) {
|
||||
BPH_mass_spring_set_vertex_mass(id, i, verts[i].mass);
|
||||
}
|
||||
|
||||
for (i = 0; i < cloth->numverts; i++) {
|
||||
for (i = 0; i < cloth->mvert_num; i++) {
|
||||
BPH_mass_spring_set_motion_state(id, i, verts[i].x, ZERO);
|
||||
}
|
||||
|
||||
@@ -115,11 +115,11 @@ void BKE_cloth_solver_set_positions(ClothModifierData *clmd)
|
||||
{
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
ClothVertex *verts = cloth->verts;
|
||||
unsigned int numverts = cloth->numverts, i;
|
||||
unsigned int mvert_num = cloth->mvert_num, i;
|
||||
ClothHairData *cloth_hairdata = clmd->hairdata;
|
||||
Implicit_Data *id = cloth->implicit;
|
||||
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
if (cloth_hairdata) {
|
||||
ClothHairData *root = &cloth_hairdata[i];
|
||||
BPH_mass_spring_set_rest_transform(id, i, root->rot);
|
||||
@@ -209,14 +209,14 @@ static void cloth_setup_constraints(ClothModifierData *clmd, ColliderContacts *c
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
Implicit_Data *data = cloth->implicit;
|
||||
ClothVertex *verts = cloth->verts;
|
||||
int numverts = cloth->numverts;
|
||||
int mvert_num = cloth->mvert_num;
|
||||
int i, j, v;
|
||||
|
||||
const float ZERO[3] = {0.0f, 0.0f, 0.0f};
|
||||
|
||||
BPH_mass_spring_clear_constraints(data);
|
||||
|
||||
for (v = 0; v < numverts; v++) {
|
||||
for (v = 0; v < mvert_num; v++) {
|
||||
if (verts[v].flags & CLOTH_VERT_FLAG_PINNED) {
|
||||
/* pinned vertex constraints */
|
||||
BPH_mass_spring_add_constraint_ndof0(data, v, ZERO); /* velocity is defined externally */
|
||||
@@ -261,15 +261,15 @@ static void cloth_setup_constraints(ClothModifierData *clmd, ColliderContacts *c
|
||||
static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothModifierData *clmd, float (*initial_cos)[3], float UNUSED(step), float dt)
|
||||
{
|
||||
Cloth *cloth= clmd->clothObject;
|
||||
float (*cos)[3] = (float (*)[3])MEM_callocN(sizeof(float)*3*cloth->numverts, "cos cloth_calc_helper_forces");
|
||||
float *masses = (float *)MEM_callocN(sizeof(float)*cloth->numverts, "cos cloth_calc_helper_forces");
|
||||
float (*cos)[3] = (float (*)[3])MEM_callocN(sizeof(float[3]) * cloth->mvert_num, "cos cloth_calc_helper_forces");
|
||||
float *masses = (float *)MEM_callocN(sizeof(float) * cloth->mvert_num, "cos cloth_calc_helper_forces");
|
||||
LinkNode *node;
|
||||
ClothSpring *spring;
|
||||
ClothVertex *cv;
|
||||
int i, steps;
|
||||
|
||||
cv = cloth->verts;
|
||||
for (i=0; i<cloth->numverts; i++, cv++) {
|
||||
for (i = 0; i < cloth->mvert_num; i++, cv++) {
|
||||
copy_v3_v3(cos[i], cv->tx);
|
||||
|
||||
if (cv->goal == 1.0f || len_squared_v3v3(initial_cos[i], cv->tx) != 0.0f) {
|
||||
@@ -317,7 +317,7 @@ static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothMo
|
||||
}
|
||||
|
||||
cv = cloth->verts;
|
||||
for (i=0; i<cloth->numverts; i++, cv++) {
|
||||
for (i = 0; i < cloth->mvert_num; i++, cv++) {
|
||||
float vec[3];
|
||||
|
||||
/*compute forces*/
|
||||
@@ -444,11 +444,11 @@ static void hair_get_boundbox(ClothModifierData *clmd, float gmin[3], float gmax
|
||||
{
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
Implicit_Data *data = cloth->implicit;
|
||||
unsigned int numverts = cloth->numverts;
|
||||
unsigned int looptri_num = cloth->tri_num;
|
||||
int i;
|
||||
|
||||
INIT_MINMAX(gmin, gmax);
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < looptri_num; i++) {
|
||||
float x[3];
|
||||
BPH_mass_spring_get_motion_state(data, i, x, NULL);
|
||||
DO_MINMAX(x, gmin, gmax);
|
||||
@@ -463,8 +463,8 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
|
||||
unsigned int i = 0;
|
||||
float drag = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */
|
||||
float gravity[3] = {0.0f, 0.0f, 0.0f};
|
||||
MFace *mfaces = cloth->mfaces;
|
||||
unsigned int numverts = cloth->numverts;
|
||||
const MVertTri *tri = cloth->tri;
|
||||
unsigned int mvert_num = cloth->mvert_num;
|
||||
ClothVertex *vert;
|
||||
|
||||
#ifdef CLOTH_FORCE_GRAVITY
|
||||
@@ -474,7 +474,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
|
||||
mul_v3_v3fl(gravity, clmd->scene->physics_settings.gravity, 0.001f * clmd->sim_parms->effector_weights->global_gravity);
|
||||
}
|
||||
vert = cloth->verts;
|
||||
for (i = 0; i < cloth->numverts; i++, vert++) {
|
||||
for (i = 0; i < cloth->mvert_num; i++, vert++) {
|
||||
BPH_mass_spring_force_gravity(data, i, vert->mass, gravity);
|
||||
}
|
||||
#endif
|
||||
@@ -488,8 +488,8 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
|
||||
/* handle external forces like wind */
|
||||
if (effectors) {
|
||||
/* cache per-vertex forces to avoid redundant calculation */
|
||||
float (*winvec)[3] = (float (*)[3])MEM_callocN(sizeof(float) * 3 * numverts, "effector forces");
|
||||
for (i = 0; i < cloth->numverts; i++) {
|
||||
float (*winvec)[3] = (float (*)[3])MEM_callocN(sizeof(float[3]) * mvert_num, "effector forces");
|
||||
for (i = 0; i < cloth->mvert_num; i++) {
|
||||
float x[3], v[3];
|
||||
EffectedPoint epoint;
|
||||
|
||||
@@ -498,13 +498,13 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
|
||||
pdDoEffectors(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < cloth->numfaces; i++) {
|
||||
MFace *mf = &mfaces[i];
|
||||
BPH_mass_spring_force_face_wind(data, mf->v1, mf->v2, mf->v3, mf->v4, winvec);
|
||||
for (i = 0; i < cloth->tri_num; i++) {
|
||||
const MVertTri *vt = &tri[i];
|
||||
BPH_mass_spring_force_face_wind(data, vt->tri[0], vt->tri[1], vt->tri[2], winvec);
|
||||
}
|
||||
|
||||
/* Hair has only edges */
|
||||
if (cloth->numfaces == 0) {
|
||||
if (cloth->tri_num == 0) {
|
||||
#if 0
|
||||
ClothHairData *hairdata = clmd->hairdata;
|
||||
ClothHairData *hair_ij, *hair_kl;
|
||||
@@ -525,7 +525,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
|
||||
ClothHairData *hairdata = clmd->hairdata;
|
||||
|
||||
vert = cloth->verts;
|
||||
for (i = 0; i < cloth->numverts; i++, vert++) {
|
||||
for (i = 0; i < cloth->mvert_num; i++, vert++) {
|
||||
if (hairdata) {
|
||||
ClothHairData *hair = &hairdata[i];
|
||||
BPH_mass_spring_force_vertex_wind(data, i, hair->radius, winvec);
|
||||
@@ -650,11 +650,11 @@ static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)
|
||||
{
|
||||
#if 0
|
||||
Implicit_Data *data = cloth->implicit;
|
||||
int numverts = cloth->numverts;
|
||||
int mvert_num = cloth->mvert_num;
|
||||
ClothVertex *vert;
|
||||
int i;
|
||||
|
||||
for (i = 0, vert = cloth->verts; i < numverts; i++, vert++) {
|
||||
for (i = 0, vert = cloth->verts; i < mvert_num; i++, vert++) {
|
||||
float x[3], v[3];
|
||||
|
||||
cloth_get_vertex_motion_state(data, vert, x, v);
|
||||
@@ -689,7 +689,7 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
|
||||
ClothSimSettings *parms = clmd->sim_parms;
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
Implicit_Data *data = cloth->implicit;
|
||||
int numverts = cloth->numverts;
|
||||
int mvert_num = cloth->mvert_num;
|
||||
ClothVertex *vert;
|
||||
|
||||
const float fluid_factor = 0.95f; /* blend between PIC and FLIP methods */
|
||||
@@ -719,7 +719,7 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
|
||||
/* main hair continuum solver */
|
||||
BPH_hair_volume_solve_divergence(grid, dt, density_target, density_strength);
|
||||
|
||||
for (i = 0, vert = cloth->verts; i < numverts; i++, vert++) {
|
||||
for (i = 0, vert = cloth->verts; i < mvert_num; i++, vert++) {
|
||||
float x[3], v[3], nv[3];
|
||||
|
||||
/* calculate volumetric velocity influence */
|
||||
@@ -799,7 +799,7 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
|
||||
ClothSimSettings *parms = clmd->sim_parms;
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
Implicit_Data *data = cloth->implicit;
|
||||
int numverts = cloth->numverts;
|
||||
int mvert_num = cloth->mvert_num;
|
||||
ClothVertex *vert;
|
||||
|
||||
/* 2.0f is an experimental value that seems to give good results */
|
||||
@@ -817,7 +817,7 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
|
||||
HairVertexGrid *vertex_grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_res, gmin, gmax);
|
||||
|
||||
vert = cloth->verts;
|
||||
for (i = 0; i < numverts; i++, vert++) {
|
||||
for (i = 0; i < mvert_num; i++, vert++) {
|
||||
float x[3], v[3];
|
||||
|
||||
if (vert->solver_index < 0) {
|
||||
@@ -832,7 +832,7 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
|
||||
BPH_hair_volume_normalize_vertex_grid(vertex_grid);
|
||||
|
||||
vert = cloth->verts;
|
||||
for (i = 0; i < numverts; i++, vert++) {
|
||||
for (i = 0; i < mvert_num; i++, vert++) {
|
||||
float x[3], v[3], f[3], dfdx[3][3], dfdv[3][3];
|
||||
|
||||
if (vert->solver_index < 0)
|
||||
@@ -858,7 +858,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
Implicit_Data *id = cloth->implicit;
|
||||
ClothVertex *verts = cloth->verts;
|
||||
int numverts = cloth->numverts;
|
||||
int mvert_num = cloth->mvert_num;
|
||||
const float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
|
||||
|
||||
bool do_extra_solve;
|
||||
@@ -870,7 +870,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
|
||||
return;
|
||||
|
||||
// update verts to current positions
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
BPH_mass_spring_get_new_position(id, i, verts[i].tx);
|
||||
|
||||
sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
|
||||
@@ -878,7 +878,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
|
||||
}
|
||||
|
||||
#if 0 /* unused */
|
||||
for (i=0, cv=cloth->verts; i<cloth->numverts; i++, cv++) {
|
||||
for (i=0, cv=cloth->verts; i<cloth->mvert_num; i++, cv++) {
|
||||
copy_v3_v3(initial_cos[i], cv->tx);
|
||||
}
|
||||
#endif
|
||||
@@ -888,7 +888,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
|
||||
do_extra_solve = cloth_bvh_objcollision(ob, clmd, step / clmd->sim_parms->timescale, dt / clmd->sim_parms->timescale);
|
||||
|
||||
// copy corrected positions back to simulation
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
float curx[3];
|
||||
BPH_mass_spring_get_position(id, i, curx);
|
||||
// correct velocity again, just to be sure we had to change it due to adaptive collisions
|
||||
@@ -898,7 +898,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis
|
||||
if (do_extra_solve) {
|
||||
// cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
|
||||
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
|
||||
float newv[3];
|
||||
|
||||
@@ -985,7 +985,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
|
||||
float step=0.0f, tf=clmd->sim_parms->timescale;
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
ClothVertex *verts = cloth->verts/*, *cv*/;
|
||||
unsigned int numverts = cloth->numverts;
|
||||
unsigned int mvert_num = cloth->mvert_num;
|
||||
float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
|
||||
Implicit_Data *id = cloth->implicit;
|
||||
ColliderContacts *contacts = NULL;
|
||||
@@ -998,7 +998,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
|
||||
cloth_clear_result(clmd);
|
||||
|
||||
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { /* do goal stuff */
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
// update velocities with constrained velocities from pinned verts
|
||||
if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {
|
||||
float v[3];
|
||||
@@ -1013,7 +1013,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
|
||||
ImplicitSolverResult result;
|
||||
|
||||
/* copy velocities for collision */
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
BPH_mass_spring_get_motion_state(id, i, NULL, verts[i].tv);
|
||||
copy_v3_v3(verts[i].v, verts[i].tv);
|
||||
}
|
||||
@@ -1038,7 +1038,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
|
||||
// damping velocity for artistic reasons
|
||||
// this is a bad way to do it, should be removed imo - lukas_t
|
||||
if (clmd->sim_parms->vel_damping != 1.0f) {
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
float v[3];
|
||||
BPH_mass_spring_get_motion_state(id, i, NULL, v);
|
||||
mul_v3_fl(v, clmd->sim_parms->vel_damping);
|
||||
@@ -1066,7 +1066,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
|
||||
BPH_mass_spring_apply_result(id);
|
||||
|
||||
/* move pinned verts to correct position */
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) {
|
||||
if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {
|
||||
float x[3];
|
||||
@@ -1087,7 +1087,7 @@ int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *
|
||||
}
|
||||
|
||||
/* copy results back to cloth data */
|
||||
for (i = 0; i < numverts; i++) {
|
||||
for (i = 0; i < mvert_num; i++) {
|
||||
BPH_mass_spring_get_motion_state(id, i, verts[i].x, verts[i].v);
|
||||
copy_v3_v3(verts[i].txold, verts[i].x);
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ void BPH_mass_spring_force_drag(struct Implicit_Data *data, float drag);
|
||||
/* Custom external force */
|
||||
void BPH_mass_spring_force_extern(struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3]);
|
||||
/* Wind force, acting on a face */
|
||||
void BPH_mass_spring_force_face_wind(struct Implicit_Data *data, int v1, int v2, int v3, int v4, const float (*winvec)[3]);
|
||||
void BPH_mass_spring_force_face_wind(struct Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3]);
|
||||
/* Wind force, acting on an edge */
|
||||
void BPH_mass_spring_force_edge_wind(struct Implicit_Data *data, int v1, int v2, float radius1, float radius2, const float (*winvec)[3]);
|
||||
/* Wind force, acting on a vertex */
|
||||
|
||||
@@ -1424,33 +1424,16 @@ static float calc_nor_area_tri(float nor[3], const float v1[3], const float v2[3
|
||||
return normalize_v3(nor);
|
||||
}
|
||||
|
||||
static float calc_nor_area_quad(float nor[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
|
||||
{
|
||||
float n1[3], n2[3];
|
||||
|
||||
sub_v3_v3v3(n1, v1, v3);
|
||||
sub_v3_v3v3(n2, v2, v4);
|
||||
|
||||
cross_v3_v3v3(nor, n1, n2);
|
||||
return normalize_v3(nor);
|
||||
}
|
||||
|
||||
/* XXX does not support force jacobians yet, since the effector system does not provide them either */
|
||||
void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3, int v4, const float (*winvec)[3])
|
||||
void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3])
|
||||
{
|
||||
const float effector_scale = 0.02f;
|
||||
float win[3], nor[3], area;
|
||||
float factor;
|
||||
|
||||
// calculate face normal and area
|
||||
if (v4) {
|
||||
area = calc_nor_area_quad(nor, data->X[v1], data->X[v2], data->X[v3], data->X[v4]);
|
||||
factor = effector_scale * area * 0.25f;
|
||||
}
|
||||
else {
|
||||
area = calc_nor_area_tri(nor, data->X[v1], data->X[v2], data->X[v3]);
|
||||
factor = effector_scale * area / 3.0f;
|
||||
}
|
||||
/* calculate face normal and area */
|
||||
area = calc_nor_area_tri(nor, data->X[v1], data->X[v2], data->X[v3]);
|
||||
factor = effector_scale * area / 3.0f;
|
||||
|
||||
world_to_root_v3(data, v1, win, winvec[v1]);
|
||||
madd_v3_v3fl(data->F[v1], nor, factor * dot_v3v3(win, nor));
|
||||
@@ -1460,11 +1443,6 @@ void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3
|
||||
|
||||
world_to_root_v3(data, v3, win, winvec[v3]);
|
||||
madd_v3_v3fl(data->F[v3], nor, factor * dot_v3v3(win, nor));
|
||||
|
||||
if (v4) {
|
||||
world_to_root_v3(data, v4, win, winvec[v4]);
|
||||
madd_v3_v3fl(data->F[v4], nor, factor * dot_v3v3(win, nor));
|
||||
}
|
||||
}
|
||||
|
||||
static void edge_wind_vertex(const float dir[3], float length, float radius, const float wind[3], float f[3], float UNUSED(dfdx[3][3]), float UNUSED(dfdv[3][3]))
|
||||
|
||||
@@ -92,7 +92,6 @@ extern "C" {
|
||||
typedef float Scalar;
|
||||
|
||||
static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
|
||||
static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
|
||||
/* slightly extended Eigen vector class
|
||||
* with conversion to/from plain C float array
|
||||
@@ -786,33 +785,16 @@ static float calc_nor_area_tri(float nor[3], const float v1[3], const float v2[3
|
||||
return normalize_v3(nor);
|
||||
}
|
||||
|
||||
static float calc_nor_area_quad(float nor[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
|
||||
{
|
||||
float n1[3], n2[3];
|
||||
|
||||
sub_v3_v3v3(n1, v1, v3);
|
||||
sub_v3_v3v3(n2, v2, v4);
|
||||
|
||||
cross_v3_v3v3(nor, n1, n2);
|
||||
return normalize_v3(nor);
|
||||
}
|
||||
|
||||
/* XXX does not support force jacobians yet, since the effector system does not provide them either */
|
||||
void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3, int v4, const float (*winvec)[3])
|
||||
void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3])
|
||||
{
|
||||
const float effector_scale = 0.02f;
|
||||
float win[3], nor[3], area;
|
||||
float factor;
|
||||
|
||||
// calculate face normal and area
|
||||
if (v4) {
|
||||
area = calc_nor_area_quad(nor, data->X.v3(v1), data->X.v3(v2), data->X.v3(v3), data->X.v3(v4));
|
||||
factor = effector_scale * area * 0.25f;
|
||||
}
|
||||
else {
|
||||
area = calc_nor_area_tri(nor, data->X.v3(v1), data->X.v3(v2), data->X.v3(v3));
|
||||
factor = effector_scale * area / 3.0f;
|
||||
}
|
||||
area = calc_nor_area_tri(nor, data->X.v3(v1), data->X.v3(v2), data->X.v3(v3));
|
||||
factor = effector_scale * area / 3.0f;
|
||||
|
||||
world_to_root_v3(data, v1, win, winvec[v1]);
|
||||
madd_v3_v3fl(data->F.v3(v1), nor, factor * dot_v3v3(win, nor));
|
||||
@@ -822,11 +804,6 @@ void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3
|
||||
|
||||
world_to_root_v3(data, v3, win, winvec[v3]);
|
||||
madd_v3_v3fl(data->F.v3(v3), nor, factor * dot_v3v3(win, nor));
|
||||
|
||||
if (v4) {
|
||||
world_to_root_v3(data, v4, win, winvec[v4]);
|
||||
madd_v3_v3fl(data->F.v3(v4), nor, factor * dot_v3v3(win, nor));
|
||||
}
|
||||
}
|
||||
|
||||
void BPH_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, const float (*winvec)[3])
|
||||
|
||||
Reference in New Issue
Block a user