From b37bbe9024e3da2efe01c48235993b426a3bb923 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 6 Nov 2007 12:08:39 +0000 Subject: [PATCH] New: pointcache integrated with cloth. Maybe some little glitches left there --- source/blender/blenkernel/BKE_cloth.h | 2 +- source/blender/blenkernel/intern/cloth.c | 159 ++++++++++++++----- source/blender/blenkernel/intern/implicit.c | 10 +- source/blender/makesdna/DNA_cloth_types.h | 23 ++- source/blender/makesdna/DNA_modifier_types.h | 2 +- source/blender/src/buttons_object.c | 6 +- 6 files changed, 141 insertions(+), 61 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 8be27ace346..83891cc74d3 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -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 diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index eba11bfedda..9720ec6b141 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -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; diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 091a0580232..41cc9e8cef4 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -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]); } } } diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 4d75f7a3778..2441c8b721f 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -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 diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index ee28d7325c7..151e652eef0 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -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; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 2e3801135eb..70559d29f40 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -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"); }