-= Cloth cleanup =-
Fixes: - Cloth event refactor to solve 2 unknown cache bugs - Cloth vgroup refactor (faster + scalable stinnes now working) - Cloth + Collision modifier on one object crash - Editmode + faceextrude on baked cloth crash - Stiffness groups would get pinned - Correct scaled stiffness calculation - Fixes freeing error under some circumstances - Deactivating reset/cache freeing when in editmode - Autobaking setting doesn't get screwed up anymore - More than 1 collision object in a scene could explode - Pinning + not protected cache didn't reset cloth - Start simulation on first frame and not on 2nd - Maximum structstiff now correct (copy-paste error) - Loading file with baked cloth calculate the spring length correctly - Loading file behaviour improved with cache - Collision object is evaluated first (untested) - Debug output activated with rt>0 Be carefull: Files with some cloth cache or something should be regenerated.
This commit is contained in:
@@ -133,9 +133,10 @@ typedef enum
|
||||
CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled
|
||||
CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled
|
||||
CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled
|
||||
CLOTH_SIMSETTINGS_FLAG_NEW = ( 1 << 6 ), // unsued, true if cloth was just enabled
|
||||
CLOTH_SIMSETTINGS_FLAG_EDITMODE = ( 1 << 6 ), // are we in editmode? -several things disabled
|
||||
CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE = (1 << 7), /* force cache freeing */
|
||||
CLOTH_SIMSETTINGS_FLAG_SCALING = (1 << 8), /* is advanced scaling active? */
|
||||
CLOTH_SIMSETTINGS_FLAG_LOADED = (1 << 9), /* did we just got load? */
|
||||
} CLOTH_SIMSETTINGS_FLAGS;
|
||||
|
||||
/* COLLISION FLAGS */
|
||||
|
||||
@@ -153,7 +153,7 @@ void cloth_init ( ClothModifierData *clmd )
|
||||
clmd->sim_parms->mass = 1.0f;
|
||||
clmd->sim_parms->stepsPerFrame = 5;
|
||||
clmd->sim_parms->sim_time = 1.0;
|
||||
clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_NEW;
|
||||
clmd->sim_parms->flags = 0;
|
||||
clmd->sim_parms->solver_type = 0;
|
||||
clmd->sim_parms->preroll = 0;
|
||||
clmd->sim_parms->maxspringlen = 10;
|
||||
@@ -163,6 +163,7 @@ void cloth_init ( ClothModifierData *clmd )
|
||||
clmd->sim_parms->lastcachedframe = 0;
|
||||
clmd->sim_parms->editedframe = 0;
|
||||
clmd->sim_parms->autoprotect = 25;
|
||||
clmd->sim_parms->firstcachedframe = -1.0;
|
||||
|
||||
clmd->coll_parms->self_friction = 5.0;
|
||||
clmd->coll_parms->friction = 10.0;
|
||||
@@ -520,20 +521,14 @@ int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
|
||||
|
||||
fclose(fp);
|
||||
|
||||
/*
|
||||
// belongs to another location ?!?
|
||||
if((clmd->sim_parms->solver_type == 0) && (ret!=0))
|
||||
{
|
||||
implicit_set_positions(clmd);
|
||||
}
|
||||
*/
|
||||
|
||||
if(clmd->sim_parms->lastcachedframe < framenr)
|
||||
{
|
||||
if(G.rt > 0)
|
||||
printf("cloth_read_cache problem: lnex - f#: %f, lastCF: %d\n", framenr, clmd->sim_parms->lastcachedframe);
|
||||
}
|
||||
}
|
||||
|
||||
if(G.rt > 0)
|
||||
printf("cloth_read_cache: %f\n", framenr);
|
||||
|
||||
return ret;
|
||||
@@ -542,15 +537,15 @@ int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
|
||||
void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
|
||||
{
|
||||
int stack_index = -1;
|
||||
printf("cloth_clear_cache: %f\n", framenr);
|
||||
|
||||
/*
|
||||
// belongs to another location ?!?
|
||||
if(framenr>0)
|
||||
// don't do anything as long as we're in editmode!
|
||||
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
|
||||
{
|
||||
cloth_read_cache(ob, clmd, framenr);
|
||||
/* delete cache free request */
|
||||
clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
/* clear cache if specific frame cleaning requested or cache is not protected */
|
||||
if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE))
|
||||
@@ -558,11 +553,18 @@ void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
|
||||
stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
|
||||
|
||||
BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index);
|
||||
|
||||
/* update last cached frame # */
|
||||
clmd->sim_parms->lastcachedframe = framenr;
|
||||
|
||||
/* update first cached frame # */
|
||||
if((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe >=0.0))
|
||||
clmd->sim_parms->firstcachedframe = -1.0;
|
||||
|
||||
if(G.rt > 0)
|
||||
printf("cloth_clear_cache: %f\n", framenr);
|
||||
}
|
||||
|
||||
/* update last cached frame # */
|
||||
clmd->sim_parms->lastcachedframe = framenr;
|
||||
|
||||
/* delete cache free request */
|
||||
clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
|
||||
|
||||
@@ -575,10 +577,12 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
|
||||
unsigned int a;
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
|
||||
if(G.rt > 0)
|
||||
printf("cloth_write_cache: %f\n", framenr);
|
||||
|
||||
if(!cloth)
|
||||
{
|
||||
if(G.rt > 0)
|
||||
printf("cloth_write_cache: no cloth\n");
|
||||
return;
|
||||
}
|
||||
@@ -588,6 +592,7 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
|
||||
fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index);
|
||||
if(!fp)
|
||||
{
|
||||
if(G.rt > 0)
|
||||
printf("cloth_write_cache: no fp\n");
|
||||
return;
|
||||
}
|
||||
@@ -599,8 +604,14 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
|
||||
fwrite(&cloth->verts[a].v, sizeof(float),3,fp);
|
||||
}
|
||||
|
||||
/* update last cached frame # */
|
||||
clmd->sim_parms->lastcachedframe = MAX2(clmd->sim_parms->lastcachedframe, framenr);
|
||||
|
||||
/* update first cached frame # */
|
||||
if((clmd->sim_parms->firstcachedframe < 0.0) || ((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe > 0.0)))
|
||||
clmd->sim_parms->firstcachedframe = framenr;
|
||||
|
||||
if(G.rt > 0)
|
||||
printf("lcf: %d, framenr: %f\n", clmd->sim_parms->lastcachedframe, framenr);
|
||||
|
||||
fclose(fp);
|
||||
@@ -629,8 +640,18 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
|
||||
MFace *mface = NULL;
|
||||
DerivedMesh *result = NULL;
|
||||
|
||||
if(G.rt > 0)
|
||||
printf("clothModifier_do start\n");
|
||||
|
||||
/* we're getting called two times during file load,
|
||||
resulting in a not valid G.relbase on the first time (cache makes problems)
|
||||
--> just return back */
|
||||
if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_LOADED)&& (!G.relbase_valid))
|
||||
{
|
||||
clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_LOADED;
|
||||
return dm;
|
||||
}
|
||||
|
||||
result = CDDM_copy(dm);
|
||||
|
||||
if(!result)
|
||||
@@ -656,6 +677,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
|
||||
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET)
|
||||
{
|
||||
cloth_free_modifier (ob, clmd);
|
||||
if(G.rt > 0)
|
||||
printf("clothModifier_do CLOTH_SIMSETTINGS_FLAG_RESET\n");
|
||||
}
|
||||
|
||||
@@ -693,10 +715,12 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
|
||||
if ( deltaTime == 1.0f )
|
||||
cloth_write_cache(ob, clmd, framenr-1.0);
|
||||
*/
|
||||
if(G.rt > 0)
|
||||
printf("cloth_from_object NO cloth_read_cache cloth_write_cache\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(G.rt > 0)
|
||||
printf("cloth_from_object cloth_read_cache\n");
|
||||
|
||||
implicit_set_positions(clmd);
|
||||
@@ -707,33 +731,35 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
|
||||
|
||||
// only be active during a specific period:
|
||||
// that's "first frame" and "last frame" on GUI
|
||||
/*
|
||||
|
||||
// TODO: enable later again after refactoring
|
||||
if ( current_time < clmd->sim_parms->firstframe )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else if ( current_time > clmd->sim_parms->lastframe )
|
||||
{
|
||||
int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
|
||||
|
||||
if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index))
|
||||
{
|
||||
if(cloth_read_cache(ob, clmd, framenr))
|
||||
{
|
||||
int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
|
||||
|
||||
if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index))
|
||||
{
|
||||
if(cloth_read_cache(ob, clmd, clmd->sim_parms->lastcachedframe))
|
||||
{
|
||||
implicit_set_positions(clmd);
|
||||
|
||||
// Copy the result back to the object.
|
||||
cloth_to_object (ob, clmd, result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
cloth_to_object (ob, clmd, result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* nice moving one frame forward */
|
||||
if ( deltaTime == 1.0f )
|
||||
{
|
||||
clmd->sim_parms->sim_time = current_time;
|
||||
|
||||
if(G.rt > 0)
|
||||
printf("clothModifier_do deltaTime=1\n");
|
||||
|
||||
if(!cloth_read_cache(ob, clmd, framenr))
|
||||
@@ -766,14 +792,16 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
|
||||
// check for autoprotection
|
||||
if(framenr >= clmd->sim_parms->autoprotect)
|
||||
{
|
||||
if(G.rt > 0)
|
||||
printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect);
|
||||
clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT;
|
||||
}
|
||||
|
||||
if(G.rt > 0)
|
||||
printf("clothModifier_do deltaTime=1 cachewrite\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(G.rt > 0)
|
||||
printf("clothModifier_do deltaTime=1 cacheread\n");
|
||||
implicit_set_positions(clmd);
|
||||
}
|
||||
@@ -783,6 +811,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
|
||||
}
|
||||
else if(deltaTime == 0.0f)
|
||||
{
|
||||
if(G.rt > 0)
|
||||
printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n");
|
||||
if(cloth_read_cache(ob, clmd, framenr))
|
||||
{
|
||||
@@ -802,6 +831,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
|
||||
}
|
||||
else
|
||||
{
|
||||
if(G.rt > 0)
|
||||
printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n");
|
||||
if(cloth_read_cache(ob, clmd, framenr))
|
||||
{
|
||||
@@ -885,7 +915,7 @@ void cloth_free_modifier ( Object *ob, ClothModifierData *clmd )
|
||||
void cloth_free_modifier_extern ( ClothModifierData *clmd )
|
||||
{
|
||||
Cloth *cloth = NULL;
|
||||
|
||||
if(G.rt > 0)
|
||||
printf("cloth_free_modifier_extern\n");
|
||||
|
||||
if ( !clmd )
|
||||
@@ -895,6 +925,7 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd )
|
||||
|
||||
if ( cloth )
|
||||
{
|
||||
if(G.rt > 0)
|
||||
printf("cloth_free_modifier_extern in\n");
|
||||
|
||||
// If our solver provides a free function, call it
|
||||
@@ -1070,12 +1101,13 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
|
||||
MVert *mvert = NULL;
|
||||
ClothVertex *verts = NULL;
|
||||
float tnull[3] = {0,0,0};
|
||||
int cache_there = 0;
|
||||
|
||||
// If we have a clothObject, free it.
|
||||
if ( clmd->clothObject != NULL )
|
||||
{
|
||||
cloth_free_modifier ( ob, clmd );
|
||||
|
||||
if(G.rt > 0)
|
||||
printf("cloth_free_modifier cloth_from_object\n");
|
||||
}
|
||||
|
||||
@@ -1098,66 +1130,73 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
|
||||
|
||||
cloth_from_mesh ( ob, clmd, dm );
|
||||
|
||||
if ( clmd->clothObject != NULL )
|
||||
if((clmd->sim_parms->firstcachedframe < 0.0) || ((clmd->sim_parms->firstcachedframe >= 0.0) && (!cloth_read_cache(ob, clmd, clmd->sim_parms->firstcachedframe))))
|
||||
{
|
||||
// create springs
|
||||
clmd->clothObject->springs = NULL;
|
||||
clmd->clothObject->numsprings = -1;
|
||||
|
||||
mvert = dm->getVertArray ( dm );
|
||||
verts = clmd->clothObject->verts;
|
||||
// no cache there
|
||||
cache_there = 0;
|
||||
if(G.rt > 0)
|
||||
printf("cache_there = 0\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have a cache
|
||||
cache_there = 1;
|
||||
if(G.rt > 0)
|
||||
printf("cache_there = 1, fcf: %d\n", clmd->sim_parms->firstcachedframe);
|
||||
}
|
||||
|
||||
// create springs
|
||||
clmd->clothObject->springs = NULL;
|
||||
clmd->clothObject->numsprings = -1;
|
||||
|
||||
mvert = dm->getVertArray ( dm );
|
||||
verts = clmd->clothObject->verts;
|
||||
|
||||
// set initial values
|
||||
for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ )
|
||||
// set initial values
|
||||
for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ )
|
||||
{
|
||||
if(!cache_there)
|
||||
{
|
||||
VECCOPY ( verts->x, mvert[i].co );
|
||||
|
||||
if(i<5)
|
||||
printf("i: %d, verts->x[0]: %f\n", i, verts->x[0]);
|
||||
|
||||
Mat4MulVecfl ( ob->obmat, verts->x );
|
||||
|
||||
if(i<5)
|
||||
printf("i: %d, verts->x[0]: %f\n\n", i, verts->x[0]);
|
||||
|
||||
verts->mass = clmd->sim_parms->mass;
|
||||
|
||||
if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
|
||||
verts->goal= clmd->sim_parms->defgoal;
|
||||
else
|
||||
verts->goal= 0.0f;
|
||||
|
||||
verts->flags = 0;
|
||||
VECCOPY ( verts->xold, verts->x );
|
||||
VECCOPY ( verts->xconst, verts->x );
|
||||
VECCOPY ( verts->txold, verts->x );
|
||||
VecMulf ( verts->v, 0.0f );
|
||||
|
||||
verts->impulse_count = 0;
|
||||
VECCOPY ( verts->impulse, tnull );
|
||||
}
|
||||
|
||||
// apply / set vertex groups
|
||||
// has to be happen before springs are build!
|
||||
cloth_apply_vgroup (clmd, dm);
|
||||
|
||||
if ( !cloth_build_springs ( clmd, dm ) )
|
||||
{
|
||||
cloth_free_modifier ( ob, clmd );
|
||||
modifier_setError ( & ( clmd->modifier ), "Can't build springs." );
|
||||
printf("cloth_free_modifier cloth_build_springs\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// init our solver
|
||||
if ( solvers [clmd->sim_parms->solver_type].init )
|
||||
solvers [clmd->sim_parms->solver_type].init ( ob, clmd );
|
||||
verts->mass = clmd->sim_parms->mass;
|
||||
|
||||
clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon );
|
||||
|
||||
return 1;
|
||||
if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
|
||||
verts->goal= clmd->sim_parms->defgoal;
|
||||
else
|
||||
verts->goal= 0.0f;
|
||||
|
||||
verts->flags = 0;
|
||||
VECCOPY ( verts->xold, verts->x );
|
||||
VECCOPY ( verts->xconst, verts->x );
|
||||
VECCOPY ( verts->txold, verts->x );
|
||||
VecMulf ( verts->v, 0.0f );
|
||||
|
||||
verts->impulse_count = 0;
|
||||
VECCOPY ( verts->impulse, tnull );
|
||||
}
|
||||
return 0;
|
||||
|
||||
// apply / set vertex groups
|
||||
// has to be happen before springs are build!
|
||||
cloth_apply_vgroup (clmd, dm);
|
||||
|
||||
if ( !cloth_build_springs ( clmd, dm ) )
|
||||
{
|
||||
cloth_free_modifier ( ob, clmd );
|
||||
modifier_setError ( & ( clmd->modifier ), "Can't build springs." );
|
||||
printf("cloth_free_modifier cloth_build_springs\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// init our solver
|
||||
if ( solvers [clmd->sim_parms->solver_type].init )
|
||||
solvers [clmd->sim_parms->solver_type].init ( ob, clmd );
|
||||
|
||||
clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -561,7 +561,7 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa
|
||||
|
||||
// Apply the impulse and increase impulse counters.
|
||||
|
||||
/*
|
||||
/*
|
||||
// calculateFrictionImpulse(tangential, collvel, collpair->normal, magtangent, clmd->coll_parms->friction*0.01, magtangent);
|
||||
VECSUBS(vrel_t_pre, collvel, collpair->normal, magnormal);
|
||||
// VecMulf(vrel_t_pre, clmd->coll_parms->friction*0.01f/INPR(vrel_t_pre,vrel_t_pre));
|
||||
@@ -1097,6 +1097,14 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
|
||||
// verts come from clmd
|
||||
for(i = 0; i < numverts; i++)
|
||||
{
|
||||
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
|
||||
{
|
||||
if(verts [i].goal >= SOFTGOALSNAP)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -82,7 +82,7 @@ void itend(void)
|
||||
double itval()
|
||||
{
|
||||
return ((double)_itend.QuadPart -
|
||||
(double)_itstart.QuadPart)/((double)ifreq.QuadPart);
|
||||
(double)_itstart.QuadPart)/((double)ifreq.QuadPart);
|
||||
}
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
@@ -91,9 +91,9 @@ double itval()
|
||||
// #include <pmmintrin.h>
|
||||
// #include <pthread.h>
|
||||
|
||||
static struct timeval _itstart, _itend;
|
||||
static struct timezone itz;
|
||||
void itstart(void)
|
||||
static struct timeval _itstart, _itend;
|
||||
static struct timezone itz;
|
||||
void itstart(void)
|
||||
{
|
||||
gettimeofday(&_itstart, &itz);
|
||||
}
|
||||
@@ -331,7 +331,7 @@ DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3])
|
||||
DO_INLINE float det_fmatrix(float m[3][3])
|
||||
{
|
||||
return m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0]
|
||||
-m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2];
|
||||
-m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2];
|
||||
}
|
||||
DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3])
|
||||
{
|
||||
@@ -719,6 +719,9 @@ int implicit_init (Object *ob, ClothModifierData *clmd)
|
||||
ClothSpring *spring = NULL;
|
||||
Implicit_Data *id = NULL;
|
||||
LinkNode *search = NULL;
|
||||
|
||||
if(G.rt > 0)
|
||||
printf("implicit_init\n");
|
||||
|
||||
// init memory guard
|
||||
// MEMORY_BASE.first = MEMORY_BASE.last = NULL;
|
||||
@@ -776,7 +779,7 @@ int implicit_init (Object *ob, ClothModifierData *clmd)
|
||||
|
||||
// dFdV_start[i].c = big_I[i].c = big_zero[i].c =
|
||||
id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c =
|
||||
id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl;
|
||||
id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = spring->kl;
|
||||
|
||||
spring->matrix_index = i + cloth->numverts;
|
||||
|
||||
@@ -1023,7 +1026,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma
|
||||
del_lfvector(p);
|
||||
del_lfvector(r);
|
||||
|
||||
// printf("iterations: %d\n", iterations);
|
||||
printf("iterations: %d\n", iterations);
|
||||
|
||||
return iterations<conjgrad_looplimit;
|
||||
}
|
||||
@@ -1109,13 +1112,13 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
|
||||
/*
|
||||
if(length>L)
|
||||
{
|
||||
if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)
|
||||
&& ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring!
|
||||
{
|
||||
s->flags |= CSPRING_FLAG_DEACTIVATE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)
|
||||
&& ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring!
|
||||
{
|
||||
s->flags |= CSPRING_FLAG_DEACTIVATE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
*/
|
||||
mul_fvector_S(dir, extent, 1.0f/length);
|
||||
}
|
||||
@@ -1133,8 +1136,18 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
|
||||
|
||||
k = clmd->sim_parms->structural;
|
||||
|
||||
scaling = k + s->stiffness * (clmd->sim_parms->max_struct-k);
|
||||
scaling = k + s->stiffness * ABS(clmd->sim_parms->max_struct-k);
|
||||
k = scaling;
|
||||
|
||||
// printf("scaling: %f, stiffness: %f\n", k, s->stiffness);
|
||||
/*
|
||||
if((s->ij == 109) || (s->kl == 109))
|
||||
{
|
||||
printf("length-L: %f, f: %f, len: %f, L: %f\n", length-L, (k*(length-L)), length, L);
|
||||
printf("kl X-x: %f, f-y: %f, f-z: %f\n", X[s->kl][0], X[s->kl][1], X[s->kl][2]);
|
||||
printf("ij X-x: %f, f-y: %f, f-z: %f\n\n", X[s->ij][0], X[s->ij][1], X[s->ij][2]);
|
||||
}
|
||||
*/
|
||||
|
||||
mul_fvector_S(stretch_force, dir, (k*(length-L)));
|
||||
|
||||
@@ -1157,7 +1170,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
|
||||
|
||||
k = clmd->sim_parms->bending;
|
||||
|
||||
scaling = k + s->stiffness * (clmd->sim_parms->max_bend-k);
|
||||
scaling = k + s->stiffness * ABS(clmd->sim_parms->max_bend-k);
|
||||
cb = k = scaling;
|
||||
|
||||
mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb));
|
||||
@@ -1166,6 +1179,12 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
|
||||
dfdx_spring_type2(s->dfdx, dir,length,L,k, cb);
|
||||
}
|
||||
}
|
||||
/*
|
||||
if((s->ij == 109) || (s->kl == 109))
|
||||
{
|
||||
printf("type: %d, f-x: %f, f-y: %f, f-z: %f\n", s->type, s->f[0], s->f[1], s->f[2]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX)
|
||||
@@ -1258,7 +1277,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
|
||||
init_lfvector(lF, gravity, numverts);
|
||||
|
||||
submul_lfvectorS(lF, lV, spring_air, numverts);
|
||||
|
||||
|
||||
/* do goal stuff */
|
||||
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
|
||||
{
|
||||
@@ -1275,22 +1294,24 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
|
||||
ks = 1.0f/(1.0f- verts [i].goal*clmd->sim_parms->goalspring)-1.0f ;
|
||||
VECADDS(lF[i], lF[i], auxvect, -ks);
|
||||
|
||||
// calulate damping forces generated by goals
|
||||
// calulate damping forces generated by goals
|
||||
|
||||
VECSUB(velgoal,verts[i].xold, verts[i].xconst);
|
||||
kd = clmd->sim_parms->goalfrict * 0.01f; // friction force scale taken from SB
|
||||
VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* handle external forces like wind */
|
||||
if(effectors)
|
||||
{
|
||||
float speed[3] = {0.0f, 0.0f,0.0f};
|
||||
float force[3]= {0.0f, 0.0f, 0.0f};
|
||||
|
||||
#pragma omp parallel for private (i) shared(lF)
|
||||
#pragma omp parallel for private (i) shared(lF)
|
||||
for(i = 0; i < cloth->numverts; i++)
|
||||
{
|
||||
float vertexnormal[3]={0,0,0};
|
||||
@@ -1308,7 +1329,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
|
||||
VECADDS(lF[i], lF[i], wind_normalized, -calculateVertexWindForce(speed, vertexnormal));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// calculate spring forces
|
||||
search = cloth->springs;
|
||||
while(search)
|
||||
@@ -1329,6 +1350,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
|
||||
cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX);
|
||||
search = search->next;
|
||||
}
|
||||
// printf("\n");
|
||||
}
|
||||
|
||||
void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *P, fmatrix3x3 *Pinv)
|
||||
@@ -1391,11 +1413,23 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
|
||||
effectors= pdInitEffectors(ob,NULL);
|
||||
|
||||
// calculate
|
||||
cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step );
|
||||
cloth_calc_force(clmd, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step );
|
||||
|
||||
// printf("F -> x: %f, y: %f; z: %f\n\n", id->F[109][0], id->F[109][1], id->F[109][2]);
|
||||
|
||||
simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv);
|
||||
|
||||
add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts);
|
||||
|
||||
/*
|
||||
printf("dt: %f\n", dt);
|
||||
printf("Xnew -> x: %f, y: %f; z: %f\n", id->Xnew[109][0], id->Xnew[109][1], id->Xnew[109][2]);
|
||||
printf("X -> x: %f, y: %f; z: %f\n", id->X[109][0], id->X[109][1], id->X[109][2]);
|
||||
printf("Vnew -> x: %f, y: %f; z: %f\n\n", id->Vnew[109][0], id->Vnew[109][1], id->Vnew[109][2]);
|
||||
*/
|
||||
|
||||
// clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_ENABLED;
|
||||
|
||||
if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
|
||||
{
|
||||
// collisions
|
||||
@@ -1404,7 +1438,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
|
||||
// update verts to current positions
|
||||
for(i = 0; i < numverts; i++)
|
||||
{
|
||||
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */
|
||||
|
||||
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
|
||||
{
|
||||
if(verts [i].goal >= SOFTGOALSNAP)
|
||||
{
|
||||
@@ -1431,6 +1466,16 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
|
||||
{
|
||||
if(result)
|
||||
{
|
||||
|
||||
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
|
||||
{
|
||||
if(verts [i].goal >= SOFTGOALSNAP)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
|
||||
|
||||
VECCOPY(verts[i].txold, verts[i].tx);
|
||||
@@ -1515,5 +1560,7 @@ void implicit_set_positions (ClothModifierData *clmd)
|
||||
{
|
||||
VECCOPY(id->X[i], verts[i].x);
|
||||
VECCOPY(id->V[i], verts[i].v);
|
||||
}
|
||||
}
|
||||
if(G.rt > 0)
|
||||
printf("implicit_set_positions\n");
|
||||
}
|
||||
|
||||
@@ -4987,7 +4987,6 @@ static void clothModifier_updateDepgraph(
|
||||
|
||||
Base *base;
|
||||
|
||||
/* TODO: this belongs to collision modifier */
|
||||
if(clmd)
|
||||
{
|
||||
for(base = G.scene->base.first; base; base= base->next)
|
||||
@@ -4995,14 +4994,11 @@ static void clothModifier_updateDepgraph(
|
||||
Object *ob1= base->object;
|
||||
if(ob1 != ob)
|
||||
{
|
||||
ClothModifierData *coll_clmd = (ClothModifierData *)modifiers_findByType(ob1, eModifierType_Cloth);
|
||||
CollisionModifierData *coll_clmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision);
|
||||
if(coll_clmd)
|
||||
{
|
||||
if (coll_clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ)
|
||||
{
|
||||
DagNode *curNode = dag_get_node(forest, ob1);
|
||||
dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
|
||||
}
|
||||
{
|
||||
DagNode *curNode = dag_get_node(forest, ob1);
|
||||
dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5220,6 +5216,7 @@ static void collisionModifier_deformVerts(
|
||||
dm->release(dm);
|
||||
}
|
||||
|
||||
|
||||
/* Boolean */
|
||||
|
||||
static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
|
||||
@@ -3015,6 +3015,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
||||
clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
|
||||
clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
|
||||
|
||||
clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_LOADED;
|
||||
clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
|
||||
|
||||
}
|
||||
else if (md->type==eModifierType_Collision) {
|
||||
|
||||
|
||||
@@ -82,6 +82,8 @@ typedef struct SimulationSettings
|
||||
float max_bend; /* max bending scaling value, min is "bending" */
|
||||
float max_struct; /* max structural scaling value, min is "structural" */
|
||||
float max_shear; /* max shear scaling value, UNUSED */
|
||||
int firstcachedframe;
|
||||
int pad;
|
||||
}
|
||||
SimulationSettings;
|
||||
|
||||
|
||||
@@ -2352,6 +2352,10 @@ void do_object_panels(unsigned short event)
|
||||
ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
|
||||
if(clmd)
|
||||
{
|
||||
// do nothing in editmode
|
||||
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
|
||||
break;
|
||||
|
||||
/* force freeing because user wants */
|
||||
clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
|
||||
|
||||
@@ -2372,6 +2376,10 @@ void do_object_panels(unsigned short event)
|
||||
ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
|
||||
if(clmd)
|
||||
{
|
||||
// do nothing in editmode
|
||||
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
|
||||
break;
|
||||
|
||||
/* force freeing because user wants */
|
||||
clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
|
||||
|
||||
@@ -2386,6 +2394,10 @@ void do_object_panels(unsigned short event)
|
||||
ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
|
||||
if(clmd)
|
||||
{
|
||||
// do nothing in editmode
|
||||
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
|
||||
break;
|
||||
|
||||
CFRA= 1;
|
||||
update_for_newframe_muted();
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
@@ -5211,8 +5223,8 @@ static void object_panel_cloth_II(Object *ob)
|
||||
|
||||
if(clmd)
|
||||
{
|
||||
uiDefButI(block, NUM, B_DIFF, "First Frame:", 10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts");
|
||||
uiDefButI(block, NUM, B_DIFF, "Last Frame:", 160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation stops");
|
||||
uiDefButI(block, NUM, B_CLOTH_RENEW, "First Frame:",10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts");
|
||||
uiDefButI(block, NUM, B_CLOTH_RENEW, "Last Frame:",160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation stops");
|
||||
|
||||
uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, "");
|
||||
|
||||
@@ -5244,6 +5256,7 @@ static void object_panel_cloth_II(Object *ob)
|
||||
{
|
||||
uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in, can be changed for each frame");
|
||||
uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Collision Quality:", 10,40,300,20, &clmd->coll_parms->loop_count, 1.0, 100.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower), can be changed for each frame");
|
||||
uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Friction:", 10,40,300,20, &clmd->coll_parms->friction, 1.0, 100.0, 1.0, 0, "Friction force if a collision happened");
|
||||
}
|
||||
else
|
||||
uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, "");
|
||||
@@ -5330,9 +5343,9 @@ static void object_panel_cloth_III(Object *ob)
|
||||
MEM_freeN (clvg1);
|
||||
MEM_freeN (clvg2);
|
||||
|
||||
uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 1000.0, 0.01f, 0, "Maximum structural stiffness value");
|
||||
uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 10000.0, 0.01f, 0, "Maximum structural stiffness value");
|
||||
|
||||
uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 1000.0, 0.01f, 0, "Maximum bending stiffness value");
|
||||
uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 10000.0, 0.01f, 0, "Maximum bending stiffness value");
|
||||
|
||||
}
|
||||
else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)
|
||||
|
||||
@@ -862,10 +862,11 @@ void make_editMesh()
|
||||
cloth_enabled = 1;
|
||||
|
||||
clmd->sim_parms->editedframe = G.scene->r.cfra;
|
||||
clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_EDITMODE;
|
||||
|
||||
/* inverse matrix is not uptodate... */
|
||||
Mat4Invert ( G.obedit->imat, G.obedit->obmat );
|
||||
|
||||
if(G.rt > 0)
|
||||
printf("make_editmesh --> cloth_enabled\n");
|
||||
}
|
||||
}
|
||||
@@ -1017,8 +1018,6 @@ void load_editMesh(void)
|
||||
Cloth *cloth = NULL;
|
||||
float temp[3], dt = 0.0;
|
||||
|
||||
printf("loadmesh\n");
|
||||
|
||||
#ifdef WITH_VERSE
|
||||
if(em->vnode) {
|
||||
struct VNode *vnode = (VNode*)em->vnode;
|
||||
@@ -1106,6 +1105,7 @@ void load_editMesh(void)
|
||||
Mat4Invert ( G.obedit->imat, G.obedit->obmat );
|
||||
dt = 1.0f / clmd->sim_parms->stepsPerFrame;
|
||||
}
|
||||
if(G.rt > 0)
|
||||
printf("loadmesh --> tot: %d, num: %d\n", G.totvert, cloth->numverts);
|
||||
}
|
||||
}
|
||||
@@ -1115,6 +1115,7 @@ void load_editMesh(void)
|
||||
|
||||
if(cloth_enabled)
|
||||
{
|
||||
if(G.rt > 0)
|
||||
printf("loadmesh --> cloth_enabled\n");
|
||||
|
||||
VECCOPY(temp, cloth->verts[i].x);
|
||||
@@ -1129,6 +1130,7 @@ void load_editMesh(void)
|
||||
*/
|
||||
if(oldverts) {
|
||||
VECCOPY(mvert->co, oldverts[i].co);
|
||||
if(G.rt > 0)
|
||||
printf("loadmesh --> cloth_enabled oldverts\n");
|
||||
}
|
||||
i++;
|
||||
@@ -1166,6 +1168,7 @@ void load_editMesh(void)
|
||||
/* burn changes to cache */
|
||||
if(cloth_enabled)
|
||||
{
|
||||
if(G.rt > 0)
|
||||
printf("loadmesh --> cloth_enabled cloth_write_cache\n");
|
||||
cloth_write_cache(G.obedit, clmd, clmd->sim_parms->editedframe);
|
||||
|
||||
@@ -1174,14 +1177,17 @@ void load_editMesh(void)
|
||||
{
|
||||
cloth_read_cache(G.obedit, clmd, G.scene->r.cfra);
|
||||
}
|
||||
clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(modifiers_isClothEnabled(G.obedit)) {
|
||||
ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(G.obedit, eModifierType_Cloth);
|
||||
if(G.rt > 0)
|
||||
printf("loadmesh --> CLOTH_SIMSETTINGS_FLAG_RESET\n");
|
||||
/* only reset cloth when no cache was used */
|
||||
clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
|
||||
clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user