New: pointcache integrated with cloth. Maybe some little glitches left there

This commit is contained in:
2007-11-06 12:08:39 +00:00
parent cbc941e342
commit b37bbe9024
6 changed files with 141 additions and 61 deletions

View File

@@ -118,7 +118,7 @@ typedef enum
// needed for buttons_object.c
// void cloth_cache_free ( ClothModifierData *clmd, float time );
void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr);
void cloth_free_modifier ( ClothModifierData *clmd );
// needed for cloth.c

View File

@@ -39,15 +39,15 @@
/* types */
#include "DNA_curve_types.h"
#include "DNA_cloth_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_cloth_types.h"
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_lattice_types.h"
#include "DNA_scene_types.h"
#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -55,6 +55,8 @@
#include "BLI_linklist.h"
#include "BKE_curve.h"
#include "BKE_cloth.h"
#include "BKE_collisions.h"
#include "BKE_deform.h"
#include "BKE_DerivedMesh.h"
#include "BKE_cdderivedmesh.h"
@@ -63,12 +65,11 @@
#include "BKE_global.h"
#include "BKE_key.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_cloth.h"
#include "BKE_collisions.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_pointcache.h"
#include "BKE_utildefines.h"
#include "BKE_DerivedMesh.h"
#include "BIF_editdeform.h"
#include "BIF_editkey.h"
#include "DNA_screen_types.h"
@@ -403,10 +404,89 @@ DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm)
return NULL;
}
/**
* cloth_deform_verts - simulates one step, framenr is in frames.
*
**/
int modifiers_indexInObject(Object *ob, ModifierData *md_seek);
void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
{
int stack_index = -1;
if(!(clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
{
stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
PTCache_id_clear((ID *)ob, framenr, stack_index);
}
}
static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
{
FILE *fp = NULL;
int stack_index = -1;
unsigned int a;
Cloth *cloth = clmd->clothObject;
if(!cloth)
return;
stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
fp = PTCache_id_fopen((ID *)ob, 'w', framenr, stack_index);
if(!fp) return;
for(a = 0; a < cloth->numverts; a++)
{
fwrite(&cloth->x[a], sizeof(float),3,fp);
fwrite(&cloth->xconst[a], sizeof(float),3,fp);
fwrite(&cloth->v[a], sizeof(float),3,fp);
}
fclose(fp);
}
static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
{
FILE *fp = NULL;
int stack_index = -1;
unsigned int a, ret = 1;
Cloth *cloth = clmd->clothObject;
if(!cloth)
return 0;
stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
fp = PTCache_id_fopen((ID *)ob, 'r', framenr, stack_index);
if(!fp)
ret = 0;
else {
for(a = 0; a < cloth->numverts; a++)
{
if(fread(&cloth->x[a], sizeof(float), 3, fp) != 3)
{
ret = 0;
break;
}
if(fread(&cloth->xconst[a], sizeof(float), 3, fp) != 3)
{
ret = 0;
break;
}
if(fread(&cloth->v[a], sizeof(float), 3, fp) != 3)
{
ret = 0;
break;
}
}
fclose(fp);
}
implicit_set_positions(clmd);
return ret;
}
/************************************************
* clothModifier_do - main simulation function
************************************************/
DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
{
unsigned int i;
@@ -421,7 +501,6 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
unsigned int framenr = (float)G.scene->r.cfra;
float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
ListBase *effectors = NULL;
ClothVertex *verts = NULL;
float deltaTime = current_time - clmd->sim_parms.sim_time;
clmd->sim_parms.dt = 1.0f / (clmd->sim_parms.stepsPerFrame * G.scene->r.frs_sec);
@@ -441,7 +520,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
mface = CDDM_get_faces(result);
clmd->sim_parms.sim_time = current_time;
if ( current_time < clmd->sim_parms.firstframe )
return result;
// only be active during a specific period:
// that's "first frame" and "last frame" on GUI
/*
@@ -501,20 +583,18 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
// Insure we have a clmd->clothObject, in case allocation failed.
if (clmd->clothObject != NULL)
{
// if(!cloth_cache_search_frame(clmd, framenr))
if(!cloth_read_cache(ob, clmd, framenr))
{
verts = cloth->verts;
// Force any pinned verts to their constrained location.
// has to be commented for verlet
for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ )
for ( i = 0; i < clmd->clothObject->numverts; i++ )
{
// Save the previous position.
VECCOPY ( cloth->xold[i], verts->xconst );
VECCOPY ( cloth->xold[i], cloth->xconst[i] );
VECCOPY ( cloth->current_xold[i], cloth->x[i] );
// Get the current position.
VECCOPY ( verts->xconst, mvert[i].co );
Mat4MulVecfl ( ob->obmat, verts->xconst );
VECCOPY ( cloth->xconst[i], mvert[i].co );
Mat4MulVecfl ( ob->obmat, cloth->xconst[i] );
}
tstart();
@@ -527,13 +607,8 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
printf("Cloth simulation time: %f\n", tval());
// cloth_cache_set_frame(clmd, framenr);
}/*
else // just retrieve the cached frame
{
cloth_cache_get_frame(clmd, framenr);
}*/
cloth_write_cache(ob, clmd, framenr);
}
// Copy the result back to the object.
cloth_to_object (ob, result, clmd);
@@ -542,18 +617,15 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
// clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon);
}
}/*
}
else if ( ( deltaTime <= 0.0f ) || ( deltaTime > 1.0f ) )
{
if ( ( clmd->clothObject != NULL ) && ( clmd->sim_parms.cache ) )
if ( clmd->clothObject != NULL )
{
if ( cloth_cache_search_frame ( clmd, framenr ) )
{
cloth_cache_get_frame(clmd, framenr);
if(cloth_read_cache(ob, clmd, framenr))
cloth_to_object (ob, result, clmd);
}
}
}*/
}
return result;
}
@@ -569,7 +641,7 @@ void cloth_free_modifier (ClothModifierData *clmd)
cloth = clmd->clothObject;
// free our frame cache
// cloth_cache_free(clmd, 0);
// cloth_clear_cache(ob, clmd, 0);
/* Calls the solver and collision frees first as they
* might depend on data in clmd->clothObject. */
@@ -614,6 +686,10 @@ void cloth_free_modifier (ClothModifierData *clmd)
if ( cloth->current_v != NULL )
MEM_freeN ( cloth->current_v );
// Free the verts.
if ( cloth->xconst != NULL )
MEM_freeN ( cloth->xconst );
cloth->verts = NULL;
cloth->numverts = -1;
@@ -806,7 +882,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
clmd->clothObject->verts [i].goal= 0.0;
clmd->clothObject->verts [i].flags = 0;
VECCOPY(clmd->clothObject->xold[i], clmd->clothObject->x[i]);
VECCOPY(clmd->clothObject->verts [i].xconst, clmd->clothObject->x[i]);
VECCOPY(clmd->clothObject->xconst[i], clmd->clothObject->x[i]);
VECCOPY(clmd->clothObject->current_xold[i], clmd->clothObject->x[i]);
VecMulf(clmd->clothObject->v[i], 0.0);
@@ -826,7 +902,8 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
clmd->clothObject->selftree = bvh_build_from_float3(NULL, 0, clmd->clothObject->x, numverts, clmd->coll_parms.selfepsilon);
// cloth_cache_set_frame(clmd, 1);
// save initial state
cloth_write_cache(ob, clmd, framenr-1);
}
return 1;
@@ -900,6 +977,14 @@ static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *d
modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_v." );
return;
}
clmd->clothObject->xconst = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 3, "Cloth MVert_xconst" );
if ( clmd->clothObject->xconst == NULL )
{
cloth_free_modifier ( clmd );
modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xconst." );
return;
}
// save face information
clmd->clothObject->numfaces = numfaces;

View File

@@ -1369,7 +1369,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
if(verts [i].goal < SOFTGOALSNAP)
{
// current_position = xold + t * (newposition - xold)
VECSUB(tvect, verts[i].xconst, cloth->xold[i]);
VECSUB(tvect, cloth->xconst[i], cloth->xold[i]);
mul_fvector_S(tvect, tvect, time);
VECADD(tvect, tvect, cloth->xold[i]);
@@ -1378,7 +1378,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
VECADDS(lF[i], lF[i], auxvect, -ks);
// calulate damping forces generated by goals
VECSUB(velgoal, cloth->xold[i], verts[i].xconst);
VECSUB(velgoal, cloth->xold[i], cloth->xconst[i]);
kd = clmd->sim_parms.goalfrict * 0.01f; // friction force scale taken from SB
VECSUBADDSS(lF[i], velgoal, kd, lV[i], kd);
@@ -1503,7 +1503,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
// update velocities with constrained velocities from pinned verts
if(verts [i].goal >= SOFTGOALSNAP)
{
VECSUB(id->V[i], verts[i].xconst, cloth->xold[i]);
VECSUB(id->V[i], cloth->xconst[i], cloth->xold[i]);
// VecMulf(id->V[i], 1.0 / dt);
}
}
@@ -1625,8 +1625,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
}
else
{
VECCOPY(cloth->current_xold[i], verts[i].xconst);
VECCOPY(cloth->x[i], verts[i].xconst);
VECCOPY(cloth->current_xold[i], cloth->xconst[i]);
VECCOPY(cloth->x[i], cloth->xconst[i]);
}
}
}

View File

@@ -43,13 +43,11 @@
typedef struct ClothVertex
{
int flags; /* General flags per vertex. */
float xconst [3]; /* constrained position */
float mass; /* mass / weight of the vertex */
float goal; /* goal, from SB */
float impulse[3]; /* used in collision.c */
unsigned int impulse_count; /* same as above */
}
ClothVertex;
} ClothVertex;
/**
@@ -66,8 +64,7 @@ typedef struct ClothSpring
float dfdx[3][3];
float dfdv[3][3];
float f[3];
}
ClothSpring;
} ClothSpring;
@@ -108,13 +105,12 @@ typedef struct SimulationSettings
float sim_time_old;
struct LinkNode *cache;
float defgoal;
int goalfrict;
float goalfrict;
float goalspring;
int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */
int lastframe; /* frame on which simulation stops */
int firstframe; /* frame on which simulation starts */
}
SimulationSettings;
} SimulationSettings;
typedef struct CollisionSettings
@@ -126,8 +122,7 @@ typedef struct CollisionSettings
short loop_count; /* How many iterations for the collision loop. */
int flags; /* collision flags defined in BKE_cloth.h */
float selfepsilon;
}
CollisionSettings;
} CollisionSettings;
/**
@@ -143,7 +138,7 @@ CollisionSettings;
typedef struct Cloth
{
struct ClothVertex *verts; /* The vertices that represent this cloth. */
struct LinkNode *springs; /* The springs connecting the mesh. */
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;
@@ -160,10 +155,10 @@ typedef struct Cloth
float (*current_xold)[3]; /* The TEMPORARY previous position of all vertices.*/
float (*v)[3]; /* the current velocity of all vertices */
float (*current_v)[3];
struct EdgeHash *edgehash; // used for fast checking adjacent points
float (*xconst)[3];
struct EdgeHash *edgehash; /* used for fast checking adjacent points */
unsigned int numothersprings;
unsigned int numspringssave;
}
Cloth;
} Cloth;
#endif

View File

@@ -344,7 +344,7 @@ typedef struct SoftbodyModifierData {
typedef struct ClothModifierData {
ModifierData modifier;
Cloth *clothObject; /* The internal data structure for cloth. */
struct Cloth *clothObject; /* The internal data structure for cloth. */
SimulationSettings sim_parms; /* definition is in DNA_cloth_types.h */
CollisionSettings coll_parms; /* definition is in DNA_cloth_types.h */
} ClothModifierData;

View File

@@ -2187,7 +2187,7 @@ void do_object_panels(unsigned short event)
CFRA= 1;
update_for_newframe_muted();
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
// cloth_cache_free(clmd, 2);
cloth_clear_cache(ob, clmd, 2);
allqueue(REDRAWBUTSOBJECT, 0);
allqueue(REDRAWVIEW3D, 0);
}
@@ -2198,7 +2198,7 @@ void do_object_panels(unsigned short event)
ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
if(clmd)
{
// cloth_cache_free(clmd, MAX2(2.0,G.scene->r.cfra+1.0));
cloth_clear_cache(ob, clmd, MAX2(2.0,G.scene->r.cfra+1.0));
allqueue(REDRAWBUTSOBJECT, 0);
}
}
@@ -3242,7 +3242,7 @@ static void object_panel_cloth(Object *ob)
}
uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness");
uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction");
uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms.goalfrict, 0.0, 50.0, 10, 0, "Goal (vertex target position) friction");
uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms.mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms.maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
}