New: pointcache integrated with cloth. Maybe some little glitches left there
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user