Restructured many collision things again, GUI cleanup

This commit is contained in:
Daniel Genrich
2008-01-21 02:23:03 +00:00
parent 2d06f79ff9
commit 530039a429
8 changed files with 488 additions and 478 deletions

View File

@@ -129,38 +129,39 @@ void implicit_set_positions ( ClothModifierData *clmd );
void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm, float ( *vertexCos ) [3], int numverts );
// used in collision.c
typedef struct Tree
typedef struct CollisionTree
{
struct Tree *nodes[4]; // 4 children --> quad-tree
struct Tree *parent;
struct Tree *nextLeaf;
struct Tree *prevLeaf;
struct CollisionTree *nodes[4]; // 4 children --> quad-tree
struct CollisionTree *parent;
struct CollisionTree *nextLeaf;
struct CollisionTree *prevLeaf;
float bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP
unsigned int tri_index; // this saves the index of the face
// int point_index[4]; // supports up to 4 points in a leaf
int count_nodes; // how many nodes are used
int traversed; // how many nodes already traversed until this level?
int isleaf;
}
Tree;
typedef struct Tree TreeNode;
CollisionTree;
typedef struct BVH
{
unsigned int numfaces;
unsigned int numverts;
ClothVertex *verts; // just a pointer to the original datastructure
// ClothVertex *verts; // just a pointer to the original datastructure
MVert *current_x; // e.g. txold in clothvertex
MVert *current_xold; // e.g. tx in clothvertex
MFace *mfaces; // just a pointer to the original datastructure
struct LinkNode *tree;
TreeNode *root; // TODO: saving the root --> is this really needed? YES!
TreeNode *leaf_tree; /* Tail of the leaf linked list. */
TreeNode *leaf_root; /* Head of the leaf linked list. */
CollisionTree *root; // TODO: saving the root --> is this really needed? YES!
CollisionTree *leaf_tree; /* Tail of the leaf linked list. */
CollisionTree *leaf_root; /* Head of the leaf linked list. */
float epsilon; /* epslion is used for inflation of the k-dop */
int flags; /* bvhFlags */
}
BVH;
typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 );
typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree * tree1, CollisionTree * tree2 );
/////////////////////////////////////////////////
@@ -168,9 +169,15 @@ typedef void ( *CM_COLLISION_RESPONSE ) ( ClothModifierData *clmd, ClothModifier
////////////////////////////////////////////////
// needed for implicit.c
void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree * tree1, Tree * tree2 );
void bvh_collision_response ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree * tree1, CollisionTree * tree2 );
int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt );
// needed for modifier.c
BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon);
// needed for collision.c
void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving);
////////////////////////////////////////////////
@@ -180,13 +187,12 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt );
// needed for cloth.c
void bvh_free ( BVH * bvh );
BVH *bvh_build ( ClothModifierData *clmd, float epsilon );
void bvh_build (BVH *bvh);
LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr );
// needed for collision.c
int bvh_traverse ( ClothModifierData * clmd, ClothModifierData * coll_clmd, Tree * tree1, Tree * tree2, float step, CM_COLLISION_RESPONSE collision_response );
void bvh_update ( ClothModifierData * clmd, BVH * bvh, int moving );
int bvh_traverse ( ClothModifierData * clmd, ClothModifierData * coll_clmd, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response );
void bvh_update(BVH * bvh, int moving);
////////////////////////////////////////////////
@@ -199,6 +205,9 @@ void cloth_init ( ClothModifierData *clmd );
void cloth_deform_verts ( struct Object *ob, float framenr, float ( *vertexCos ) [3], int numVerts, void *derivedData, ClothModifierData *clmd );
void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface );
// needed for collision.c
void bvh_update_from_cloth(ClothModifierData *clmd, int moving);
////////////////////////////////////////////////

View File

@@ -79,6 +79,7 @@ typedef struct BVH
}
BVH;
/* used for collisions in kdop.c and also collision.c*/
typedef struct CollisionPair
{

View File

@@ -160,6 +160,7 @@ void cloth_init ( ClothModifierData *clmd )
clmd->sim_parms.maxspringlen = 10;
clmd->sim_parms.firstframe = 1;
clmd->sim_parms.lastframe = 250;
clmd->sim_parms.vgroup_mass = 0;
clmd->coll_parms.self_friction = 5.0;
clmd->coll_parms.friction = 10.0;
clmd->coll_parms.loop_count = 1;
@@ -175,13 +176,91 @@ void cloth_init ( ClothModifierData *clmd )
// also from softbodies
clmd->sim_parms.maxgoal = 1.0f;
clmd->sim_parms.mingoal = 0.0f;
clmd->sim_parms.defgoal = 0.7f;
clmd->sim_parms.defgoal = 0.0f;
clmd->sim_parms.goalspring = 100.0f;
clmd->sim_parms.goalfrict = 0.0f;
clmd->sim_parms.cache = NULL;
}
BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon)
{
unsigned int i = 0;
BVH *bvh=NULL;
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = NULL;
if(!clmd)
return NULL;
cloth = clmd->clothObject;
if(!cloth)
return NULL;
verts = cloth->verts;
bvh = MEM_callocN(sizeof(BVH), "BVH");
if (bvh == NULL)
{
printf("bvh: Out of memory.\n");
return NULL;
}
// springs = cloth->springs;
// numsprings = cloth->numsprings;
bvh->flags = 0;
bvh->leaf_tree = NULL;
bvh->leaf_root = NULL;
bvh->tree = NULL;
bvh->epsilon = epsilon;
bvh->numfaces = cloth->numfaces;
bvh->mfaces = cloth->mfaces;
bvh->numverts = cloth->numverts;
bvh->current_x = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_x" );
bvh->current_xold = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_xold" );
for(i = 0; i < bvh->numverts; i++)
{
VECCOPY(bvh->current_x[i].co, verts[i].tx);
VECCOPY(bvh->current_xold[i].co, verts[i].txold);
}
bvh_build (bvh);
return bvh;
}
void bvh_update_from_cloth(ClothModifierData *clmd, int moving)
{
unsigned int i = 0;
Cloth *cloth = clmd->clothObject;
BVH *bvh = cloth->tree;
ClothVertex *verts = cloth->verts;
if(!bvh)
return;
if(cloth->numverts!=bvh->numverts)
return;
if(cloth->verts)
{
for(i = 0; i < bvh->numverts; i++)
{
VECCOPY(bvh->current_x[i].co, verts[i].tx);
VECCOPY(bvh->current_xold[i].co, verts[i].txold);
}
}
bvh_update(bvh, moving);
}
// unused in the moment, cloth needs quads from mesh
DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm )
{
@@ -433,9 +512,9 @@ static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr
for(a = 0; a < cloth->numverts; a++)
{
fwrite(&cloth->verts[a].x, sizeof(float),4,fp);
fwrite(&cloth->verts[a].xconst, sizeof(float),4,fp);
fwrite(&cloth->verts[a].v, sizeof(float),4,fp);
fwrite(&cloth->verts[a].x, sizeof(float),3,fp);
fwrite(&cloth->verts[a].xconst, sizeof(float),3,fp);
fwrite(&cloth->verts[a].v, sizeof(float),3,fp);
}
fclose(fp);
@@ -458,17 +537,17 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
else {
for(a = 0; a < cloth->numverts; a++)
{
if(fread(&cloth->verts[a].x, sizeof(float), 4, fp) != 4)
if(fread(&cloth->verts[a].x, sizeof(float), 3, fp) != 3)
{
ret = 0;
break;
}
if(fread(&cloth->verts[a].xconst, sizeof(float), 4, fp) != 4)
if(fread(&cloth->verts[a].xconst, sizeof(float), 3, fp) != 3)
{
ret = 0;
break;
}
if(fread(&cloth->verts[a].v, sizeof(float), 4, fp) != 4)
if(fread(&cloth->verts[a].v, sizeof(float), 3, fp) != 3)
{
ret = 0;
break;
@@ -656,7 +735,7 @@ void clothModifier_do ( ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
solvers [clmd->sim_parms.solver_type].solver ( ob, framenr, clmd, effectors );
tend();
printf ( "Cloth simulation time: %f\n", ( float ) tval() );
// printf ( "Cloth simulation time: %f\n", ( float ) tval() );
cloth_write_cache(ob, clmd, framenr);
@@ -830,7 +909,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm, short
{
verts->goal = dvert->dw [j].weight;
goalfac= ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal );
goalfac= 1.0f;
/*
// Kicking goal factor to simplify things...who uses that anyway?
// ABS ( clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal );
*/
verts->goal = ( float ) pow ( verts->goal , 4.0f );
if ( dvert->dw [j].weight >=SOFTGOALSNAP )
@@ -905,7 +990,7 @@ static int collobj_from_object ( Object *ob, ClothModifierData *clmd, DerivedMes
verts->impulse_count = 0;
VECCOPY ( verts->impulse, tnull );
}
clmd->clothObject->tree = bvh_build ( clmd,clmd->coll_parms.epsilon );
clmd->clothObject->tree = bvh_build_from_cloth ( clmd,clmd->coll_parms.epsilon );
}
@@ -1012,7 +1097,7 @@ static int cloth_from_object ( Object *ob, ClothModifierData *clmd, DerivedMesh
if ( solvers [clmd->sim_parms.solver_type].init )
solvers [clmd->sim_parms.solver_type].init ( ob, clmd );
clmd->clothObject->tree = bvh_build ( clmd, clmd->coll_parms.epsilon );
clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms.epsilon );
cloth_write_cache(ob, clmd, framenr-1);
}

View File

@@ -70,7 +70,72 @@
#include "Bullet-C-Api.h"
// step is limited from 0 (frame start position) to 1 (frame end position)
void collision_move_object(CollisionModifierData *collmd, float step, float prevstep)
{
float tv[3] = {0,0,0};
unsigned int i = 0;
for ( i = 0; i < collmd->numverts; i++ )
{
VECSUB(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);
VECSUB(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co);
}
}
BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon)
{
BVH *bvh=NULL;
bvh = MEM_callocN(sizeof(BVH), "BVH");
if (bvh == NULL)
{
printf("bvh: Out of memory.\n");
return NULL;
}
bvh->flags = 0;
bvh->leaf_tree = NULL;
bvh->leaf_root = NULL;
bvh->tree = NULL;
bvh->epsilon = epsilon;
bvh->numfaces = numfaces;
bvh->mfaces = mfaces;
// we have no faces, we save seperate points
if(!mfaces)
{
bvh->numfaces = numverts;
}
bvh->numverts = numverts;
bvh->current_x = MEM_dupallocN(x);
bvh->current_xold = MEM_dupallocN(x);
bvh_build(bvh);
return bvh;
}
void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving)
{
if(!bvh)
return;
if(numverts!=bvh->numverts)
return;
if(x)
memcpy(bvh->current_xold, x, sizeof(MVert) * numverts);
if(xnew)
memcpy(bvh->current_x, xnew, sizeof(MVert) * numverts);
bvh_update(bvh, moving);
}
/**
* gsl_poly_solve_cubic -
@@ -519,7 +584,7 @@ int cloth_collision_response_moving_edges(ClothModifierData *clmd, ClothModifier
}
void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
void cloth_collision_static(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
{
CollPair *collpair = NULL;
Cloth *cloth1=NULL, *cloth2=NULL;
@@ -667,7 +732,7 @@ int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_cl
return 0;
}
void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
{
EdgeCollPair edgecollpair;
Cloth *cloth1=NULL, *cloth2=NULL;
@@ -802,7 +867,7 @@ void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *co
}
}
void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
{
CollPair collpair;
Cloth *cloth1=NULL, *cloth2=NULL;
@@ -896,7 +961,7 @@ void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *col
}
}
void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, Tree *tree1, Tree *tree2)
void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
{
// TODO: check for adjacent
cloth_collision_moving_edges(clmd, coll_clmd, tree1, tree2);
@@ -943,7 +1008,7 @@ void cloth_update_collision_objects(float step)
}
// update BVH of collision object
bvh_update(coll_clmd, coll_bvh, 0); // 0 means STATIC, 1 means MOVING
bvh_update_from_cloth(coll_clmd, 0); // 0 means STATIC, 1 means MOVING
}
else
printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
@@ -972,6 +1037,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
{
return 0;
}
cloth = clmd->clothObject;
verts = cloth->verts;
cloth_bvh = (BVH *) cloth->tree;
@@ -983,7 +1049,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
////////////////////////////////////////////////////////////
// update cloth bvh
bvh_update(clmd, cloth_bvh, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
bvh_update_from_cloth(clmd, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
// update collision objects
cloth_update_collision_objects(step);
@@ -1075,12 +1141,12 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
clmd->coll_parms.collision_list = NULL;
}
printf("ic: %d\n", ic);
// printf("ic: %d\n", ic);
rounds++;
}
while(result && (CLOTH_MAX_THRESHOLD>rounds));
printf("\n");
// printf("\n");
////////////////////////////////////////////////////////////
// update positions
@@ -1100,7 +1166,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
// update cloth bvh
bvh_update(clmd, cloth_bvh, 1); // 0 means STATIC, 1 means MOVING
bvh_update_from_cloth(clmd, 1); // 0 means STATIC, 1 means MOVING
// update moving bvh for collision object once
for (base = G.scene->base.first; base; base = base->next)
@@ -1119,7 +1185,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
{
BVH *coll_bvh = coll_clmd->clothObject->tree;
bvh_update(coll_clmd, coll_bvh, 1); // 0 means STATIC, 1 means MOVING
bvh_update_from_cloth(coll_clmd, 1); // 0 means STATIC, 1 means MOVING
}
}
@@ -1204,7 +1270,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
}
// update cloth bvh
bvh_update(clmd, cloth_bvh, 1); // 0 means STATIC, 1 means MOVING
bvh_update_from_cloth(clmd, 1); // 0 means STATIC, 1 means MOVING
// free collision list
@@ -1223,7 +1289,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
clmd->coll_parms.collision_list = NULL;
}
printf("ic: %d\n", ic);
// printf("ic: %d\n", ic);
rounds++;
}
while(result && (CLOTH_MAX_THRESHOLD>rounds));

View File

@@ -1,4 +1,4 @@
/* collision.c
/* kdop.c
*
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
@@ -38,6 +38,7 @@
#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_cloth_types.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -58,7 +59,7 @@
#include "BKE_key.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_collisions.h"
#include "BKE_cloth.h"
#include "BKE_modifier.h"
#include "BKE_utildefines.h"
#include "BKE_DerivedMesh.h"
@@ -164,13 +165,13 @@ static int size_threshold = 16;
/*
* Common methods for all algorithms
*/
void bvh_exchange(CollisionTree **a, int i, int j)
DO_INLINE void bvh_exchange(CollisionTree **a, int i, int j)
{
CollisionTree *t=a[i];
a[i]=a[j];
a[j]=t;
}
int floor_lg(int a)
DO_INLINE int floor_lg(int a)
{
return (int)(floor(log(a)/log(2)));
}
@@ -195,7 +196,7 @@ static void bvh_insertionsort(CollisionTree **a, int lo, int hi, int axis)
}
}
static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree *x, int axis)
static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree * x, int axis)
{
int i=lo, j=hi;
while (1)
@@ -215,7 +216,7 @@ static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree *x, in
*/
static void bvh_downheap(CollisionTree **a, int i, int n, int lo, int axis)
{
CollisionTree *d = a[lo+i-1];
CollisionTree * d = a[lo+i-1];
int child;
while (i<=n/2)
{
@@ -293,7 +294,7 @@ static void bvh_introsort_loop (CollisionTree **a, int lo, int hi, int depth_lim
}
}
void bvh_sort(CollisionTree **a0, int begin, int end, int axis)
DO_INLINE void bvh_sort(CollisionTree **a0, int begin, int end, int axis)
{
if (begin < end)
{
@@ -302,7 +303,7 @@ void bvh_sort(CollisionTree **a0, int begin, int end, int axis)
bvh_insertionsort(a, begin, end, axis);
}
}
void bvh_sort_along_axis(CollisionTree **face_list, int start, int end, int axis)
DO_INLINE void bvh_sort_along_axis(CollisionTree **face_list, int start, int end, int axis)
{
bvh_sort(face_list, start, end, axis);
}
@@ -330,11 +331,11 @@ void bvh_free(BVH * bvh)
BLI_linklist_free(bvh->tree,NULL);
bvh->tree = NULL;
if(bvh->x)
MEM_freeN(bvh->x);
if(bvh->xnew)
MEM_freeN(bvh->xnew);
if(bvh->current_x)
MEM_freeN(bvh->current_x);
if(bvh->current_xold)
MEM_freeN(bvh->current_xold);
MEM_freeN(bvh);
bvh = NULL;
}
@@ -342,7 +343,7 @@ void bvh_free(BVH * bvh)
// only supports x,y,z axis in the moment
// but we should use a plain and simple function here for speed sake
int bvh_largest_axis(float *bv)
DO_INLINE int bvh_largest_axis(float *bv)
{
float middle_point[3];
@@ -366,7 +367,7 @@ int bvh_largest_axis(float *bv)
}
// depends on the fact that the BVH's for each face is already build
void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
DO_INLINE void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
{
float newmin,newmax;
int i, j;
@@ -390,62 +391,35 @@ void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces,
}
}
void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
{
MVert *tempMVert = bvh->x;
float *tempBV = bv;
float newminmax;
int i, j, k;
for (j = 0; j < numfaces; j++)
{
// 1 up to 4 vertices per leaf.
for (k = 0; k < 4; k++)
{
int temp = tri[j]->point_index[k];
if(temp < 0)
continue;
// for all Axes.
for (i = KDOP_START; i < KDOP_END; i++)
{
newminmax = INPR(tempMVert[temp].co, KDOP_AXES[i]);
if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0))
tempBV[(2 * i)] = newminmax;
if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
tempBV[(2 * i) + 1] = newminmax;
}
}
}
}
void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
{
MVert *tempMVert = bvh->x;
MVert *tempMVert2 = bvh->xnew;
MFace *tempMFace = bvh->mfaces;
float *tempBV = bv;
float newminmax;
int i, j, k;
for (j = 0; j < numfaces; j++)
{
tempMFace = bvh->mfaces + (tri [j])->tri_index;
// 3 or 4 vertices per face.
for (k = 0; k < 4; k++)
{
int temp = tri[j]->point_index[k];
if(temp < 0)
int temp = 0;
// If this is a triangle.
if (k == 3 && !tempMFace->v4)
continue;
// TODO: other name for "temp" this gets all vertices of a face
if (k == 0)
temp = tempMFace->v1;
else if (k == 1)
temp = tempMFace->v2;
else if (k == 2)
temp = tempMFace->v3;
else if (k == 3)
temp = tempMFace->v4;
// for all Axes.
for (i = KDOP_START; i < KDOP_END; i++)
{
newminmax = INPR(tempMVert[temp].co, KDOP_AXES[i]);
if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0))
tempBV[(2 * i)] = newminmax;
if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
tempBV[(2 * i) + 1] = newminmax;
newminmax = INPR(tempMVert2[temp].co, KDOP_AXES[i]);
newminmax = INPR(bvh->current_xold[temp].co, KDOP_AXES[i]);
if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0))
tempBV[(2 * i)] = newminmax;
if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
@@ -455,7 +429,51 @@ void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, floa
}
}
static void bvh_div_env_node(BVH * bvh, TreeNode *tree, CollisionTree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink)
DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
{
MFace *tempMFace = bvh->mfaces;
float *tempBV = bv;
float newminmax;
int i, j, k;
for (j = 0; j < numfaces; j++)
{
tempMFace = bvh->mfaces + (tri [j])->tri_index;
// 3 or 4 vertices per face.
for (k = 0; k < 4; k++)
{
int temp = 0;
// If this is a triangle.
if (k == 3 && !tempMFace->v4)
continue;
// TODO: other name for "temp" this gets all vertices of a face
if (k == 0)
temp = tempMFace->v1;
else if (k == 1)
temp = tempMFace->v2;
else if (k == 2)
temp = tempMFace->v3;
else if (k == 3)
temp = tempMFace->v4;
// for all Axes.
for (i = KDOP_START; i < KDOP_END; i++)
{
newminmax = INPR(bvh->current_xold[temp].co, KDOP_AXES[i]);
if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0))
tempBV[(2 * i)] = newminmax;
if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
tempBV[(2 * i) + 1] = newminmax;
newminmax = INPR(bvh->current_x[temp].co, KDOP_AXES[i]);
if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0))
tempBV[(2 * i)] = newminmax;
if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
tempBV[(2 * i) + 1] = newminmax;
}
}
}
}
static void bvh_div_env_node(BVH *bvh, CollisionTree *tree, CollisionTree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink)
{
int i = 0;
CollisionTree *newtree = NULL;
@@ -523,17 +541,26 @@ static void bvh_div_env_node(BVH * bvh, TreeNode *tree, CollisionTree **face_lis
return;
}
// mfaces is allowed to be null
// just vertexes are used if mfaces=NULL
BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces)
/* function cannot be directly called - needs alloced bvh */
void bvh_build (BVH *bvh)
{
unsigned int i = 0, j = 0;
unsigned int i = 0, j = 0, k = 0;
CollisionTree **face_list=NULL;
CollisionTree *tree=NULL;
LinkNode *nlink = NULL;
tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
// TODO: check succesfull alloc
BLI_linklist_append(&bvh->tree, tree);
nlink = bvh->tree;
if (tree == NULL)
{
printf("bvh_build: Out of memory for nodes.\n");
bvh_free(bvh);
return;
}
bvh->root = bvh->tree->link;
bvh->root->isleaf = 0;
bvh->root->parent = NULL;
@@ -541,25 +568,7 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces)
if(bvh->numfaces<=1)
{
// Why that? --> only one face there
if(bvh->mfaces)
{
bvh->root->point_index[0] = mfaces[0].v1;
bvh->root->point_index[1] = mfaces[0].v2;
bvh->root->point_index[2] = mfaces[0].v3;
if(mfaces[0].v4)
bvh->root->point_index[3] = mfaces[0].v4;
else
bvh->root->point_index[3] = -1;
}
else
{
bvh->root->point_index[0] = 0;
bvh->root->point_index[1] = -1;
bvh->root->point_index[2] = -1;
bvh->root->point_index[3] = -1;
}
bvh->root->tri_index = 0; // Why that? --> only one face there
bvh->root->isleaf = 1;
bvh->root->traversed = 0;
bvh->root->count_nodes = 0;
@@ -569,46 +578,28 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces)
bvh->root->prevLeaf = NULL;
}
else
{
{
// create face boxes
face_list = MEM_callocN (bvh->numfaces * sizeof (CollisionTree *), "CollisionTree");
if (face_list == NULL)
{
printf("bvh_build: Out of memory for face_list.\n");
bvh_free(bvh);
return NULL;
return;
}
// create face boxes
for(i = 0; i < bvh->numfaces; i++)
for(i = 0, k = 0; i < bvh->numfaces; i++)
{
LinkNode *tnlink = NULL;
LinkNode *tnlink;
tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
// TODO: check succesfull alloc
tnlink = BLI_linklist_append_fast(&nlink->next, tree);
face_list[i] = tree;
if(bvh->mfaces)
{
tree->point_index[0] = mfaces[i].v1;
tree->point_index[1] = mfaces[i].v2;
tree->point_index[2] = mfaces[i].v3;
if(mfaces[i].v4)
tree->point_index[3] = mfaces[i].v4;
else
tree->point_index[3] = -1;
}
else
{
tree->point_index[0] = i;
tree->point_index[1] = -1;
tree->point_index[2] = -1;
tree->point_index[3] = -1;
}
tree->tri_index = i;
tree->isleaf = 1;
tree->nextLeaf = NULL;
tree->prevLeaf = bvh->leaf_tree;
@@ -641,170 +632,18 @@ BVH *bvh_build (BVH *bvh, MFace *mfaces, unsigned int numfaces)
// build root bvh
bvh_calc_DOP_hull_from_faces(bvh, face_list, bvh->numfaces, bvh->root->bv);
// This is the traversal function.
bvh_div_env_node(bvh, bvh->root, face_list, 0, bvh->numfaces-1, 0, nlink);
if (face_list)
MEM_freeN(face_list);
// BLI_edgehash_free(edgehash, NULL);
}
return bvh;
}
BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon)
{
BVH *bvh=NULL;
CollisionTree *tree=NULL;
bvh = MEM_callocN(sizeof(BVH), "BVH");
if (bvh == NULL)
{
printf("bvh: Out of memory.\n");
return NULL;
}
bvh->flags = 0;
bvh->leaf_tree = NULL;
bvh->leaf_root = NULL;
bvh->tree = NULL;
bvh->epsilon = epsilon;
bvh->numfaces = numfaces;
bvh->mfaces = mfaces;
// we have no faces, we save seperate points
if(!mfaces)
{
bvh->numfaces = numverts;
}
bvh->numverts = numverts;
bvh->xnew = MEM_dupallocN(x);
bvh->x = MEM_dupallocN(x);
tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
if (tree == NULL)
{
printf("bvh_build: Out of memory for nodes.\n");
bvh_free(bvh);
return NULL;
}
BLI_linklist_append(&bvh->tree, tree);
return bvh_build(bvh, mfaces, numfaces);
}
BVH *bvh_build_from_float3 (MFace *mfaces, unsigned int numfaces, float (*x)[3], unsigned int numverts, float epsilon)
{
BVH *bvh=NULL;
CollisionTree *tree=NULL;
unsigned int i = 0;
bvh = MEM_callocN(sizeof(BVH), "BVH");
if (bvh == NULL)
{
printf("bvh: Out of memory.\n");
return NULL;
}
bvh->flags = 0;
bvh->leaf_tree = NULL;
bvh->leaf_root = NULL;
bvh->tree = NULL;
bvh->epsilon = epsilon;
bvh->numfaces = numfaces;
bvh->mfaces = mfaces;
// we have no faces, we save seperate points
if(!mfaces)
{
bvh->numfaces = numverts;
}
bvh->numverts = numverts;
bvh->xnew = (MVert *)MEM_callocN(sizeof(MVert)*numverts, "BVH MVert");
for(i = 0; i < numverts; i++)
{
VECCOPY(bvh->xnew[i].co, x[i]);
}
bvh->x = MEM_dupallocN(bvh->xnew);
tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
if (tree == NULL)
{
printf("bvh_build: Out of memory for nodes.\n");
bvh_free(bvh);
return NULL;
}
BLI_linklist_append(&bvh->tree, tree);
return bvh_build(bvh, mfaces, numfaces);
}
BVH *bvh_build_from_float4 (MFace *mfaces, unsigned int numfaces, float (*x)[4], unsigned int numverts, float epsilon)
{
BVH *bvh=NULL;
CollisionTree *tree=NULL;
unsigned int i = 0;
bvh = MEM_callocN(sizeof(BVH), "BVH");
if (bvh == NULL)
{
printf("bvh: Out of memory.\n");
return NULL;
}
bvh->flags = 0;
bvh->leaf_tree = NULL;
bvh->leaf_root = NULL;
bvh->tree = NULL;
bvh->epsilon = epsilon;
bvh->numfaces = numfaces;
bvh->mfaces = mfaces;
// we have no faces, we save seperate points
if(!mfaces)
{
bvh->numfaces = numverts;
}
bvh->numverts = numverts;
bvh->xnew = (MVert *)MEM_callocN(sizeof(MVert)*numverts, "BVH MVert");
for(i = 0; i < numverts; i++)
{
VECCOPY(bvh->xnew[i].co, x[i]);
}
bvh->x = MEM_dupallocN(bvh->xnew);
tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
if (tree == NULL)
{
printf("bvh_build: Out of memory for nodes.\n");
bvh_free(bvh);
return NULL;
}
BLI_linklist_append(&bvh->tree, tree);
return bvh_build(bvh, mfaces, numfaces);
}
// bvh_overlap - is it possbile for 2 bv's to collide ?
int bvh_overlap(float *bv1, float *bv2)
DO_INLINE int bvh_overlap(float *bv1, float *bv2)
{
int i = 0;
for (i = KDOP_START; i < KDOP_END; i++)
@@ -823,6 +662,7 @@ int bvh_overlap(float *bv1, float *bv2)
return 1;
}
/**
* bvh_traverse - traverse two bvh trees looking for potential collisions.
*
@@ -830,9 +670,18 @@ int bvh_overlap(float *bv1, float *bv2)
* every other triangle that doesn't require any realloc, but uses
* much memory
*/
int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collision_list)
int bvh_traverse(ClothModifierData * clmd, ClothModifierData * coll_clmd, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response)
{
int i = 0, ret = 0;
int i = 0, ret=0;
/*
// Shouldn't be possible
if(!tree1 || !tree2)
{
printf("Error: no tree there\n");
return 0;
}
*/
if (bvh_overlap(tree1->bv, tree2->bv))
{
// Check if this node in the first tree is a leaf
@@ -841,85 +690,11 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio
// Check if this node in the second tree a leaf
if (tree2->isleaf)
{
//////////////////////////////////
// TODO: check for 3rd point if zero (triangle)!!!
//////////////////////////////////
// Provide the collision response.
CollisionPair *collpair = NULL;
if(tree1 != tree2) // do not collide same points
{
////////////////////////////////////////
// FIRST FACE
////////////////////////////////////////
// save potential colliding triangles
collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
VECCOPY(collpair->point_indexA, tree1->point_index);
VECCOPY(collpair->point_indexB, tree2->point_index);
// we use prepend because lots of insertions at end
// of list are horrible slow!
BLI_linklist_prepend(&collision_list[0], collpair);
////////////////////////////////////////
// SECOND FACE
////////////////////////////////////////
if(tree1->point_index[3]) // check for quad face
{
// save potential colliding triangles
collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
VECCOPY(collpair->point_indexA, tree1->point_index);
collpair->point_indexA[2] = tree1->point_index[3];
VECCOPY(collpair->point_indexB, tree2->point_index);
// we use prepend because lots of insertions at end
// of list are horrible slow!
BLI_linklist_prepend(&collision_list[0], collpair);
}
////////////////////////////////////////
// THIRD FACE
////////////////////////////////////////
if(tree2->point_index[3]) // check for quad face
{
// save potential colliding triangles
collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
VECCOPY(collpair->point_indexA, tree1->point_index);
VECCOPY(collpair->point_indexB, tree2->point_index);
collpair->point_indexB[2] = tree2->point_index[3];
// we use prepend because lots of insertions at end
// of list are horrible slow!
BLI_linklist_prepend(&collision_list[0], collpair);
}
////////////////////////////////////////
// FOURTH FACE
////////////////////////////////////////
if(tree1->point_index[3] && tree1->point_index[3]) // check for quad face
{
// save potential colliding triangles
collpair = (CollisionPair *)MEM_callocN(sizeof(CollisionPair), "CollisionPair");
VECCOPY(collpair->point_indexA, tree1->point_index);
collpair->point_indexA[2] = tree1->point_index[3];
VECCOPY(collpair->point_indexB, tree2->point_index);
collpair->point_indexB[2] = tree2->point_index[3];
// we use prepend because lots of insertions at end
// of list are horrible slow!
BLI_linklist_prepend(&collision_list[0], collpair);
}
return 1;
}
else
return 0;
if(collision_response)
collision_response (clmd, coll_clmd, tree1, tree2);
return 1;
}
else
{
@@ -927,7 +702,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio
for (i = 0; i < 4; i++)
{
// Only traverse nodes that exist.
if (tree2->nodes[i] && (bvh_traverse (tree1, tree2->nodes[i], collision_list)))
if (tree2->nodes[i] && bvh_traverse (clmd, coll_clmd, tree1, tree2->nodes[i], step, collision_response))
ret = 1;
}
}
@@ -938,7 +713,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio
for (i = 0; i < 4; i++)
{
// Only traverse nodes that exist.
if (tree1->nodes [i] && (bvh_traverse (tree1->nodes[i], tree2, collision_list)))
if (tree1->nodes [i] && bvh_traverse (clmd, coll_clmd, tree1->nodes[i], tree2, step, collision_response))
ret = 1;
}
}
@@ -949,7 +724,7 @@ int bvh_traverse(CollisionTree *tree1, CollisionTree *tree2, LinkNode **collisio
// bottom up update of bvh tree:
// join the 4 children here
void bvh_join(CollisionTree *tree)
void bvh_join(CollisionTree * tree)
{
int i = 0, j = 0;
if (!tree)
@@ -979,10 +754,10 @@ void bvh_join(CollisionTree *tree)
}
// update static bvh
// needs new positions in bvh->x, bvh->xnew
/* you have to update the bvh position before calling this function */
void bvh_update(BVH * bvh, int moving)
{
TreeNode *leaf, *parent;
CollisionTree *leaf, *parent;
int traversecheck = 1; // if this is zero we don't go further
unsigned int j = 0;
@@ -993,7 +768,6 @@ void bvh_update(BVH * bvh, int moving)
{
leaf->parent->traversed = 0;
}
if(!moving)
bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv);
else
@@ -1034,70 +808,3 @@ void bvh_update(BVH * bvh, int moving)
}
}
void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving)
{
if(!bvh)
return;
if(numverts!=bvh->numverts)
return;
if(x)
memcpy(bvh->x, x, sizeof(MVert) * numverts);
if(xnew)
memcpy(bvh->xnew, xnew, sizeof(MVert) * numverts);
bvh_update(bvh, moving);
}
void bvh_update_from_float3(BVH * bvh, float (*x)[3], unsigned int numverts, float (*xnew)[3], int moving)
{
unsigned int i = 0;
if(!bvh)
return;
if(numverts!=bvh->numverts)
return;
if(x)
{
for(i = 0; i < numverts; i++)
VECCOPY(bvh->x[i].co, x[i]);
}
if(xnew)
{
for(i = 0; i < numverts; i++)
VECCOPY(bvh->xnew[i].co, xnew[i]);
}
bvh_update(bvh, moving);
}
void bvh_update_from_float4(BVH * bvh, float (*x)[4], unsigned int numverts, float (*xnew)[4], int moving)
{
unsigned int i = 0;
if(!bvh)
return;
if(numverts!=bvh->numverts)
return;
if(x)
{
for(i = 0; i < numverts; i++)
VECCOPY(bvh->x[i].co, x[i]);
}
if(xnew)
{
for(i = 0; i < numverts; i++)
VECCOPY(bvh->xnew[i].co, xnew[i]);
}
bvh_update(bvh, moving);
}

View File

@@ -75,6 +75,7 @@
#include "BKE_main.h"
#include "BKE_anim.h"
#include "BKE_bad_level_calls.h"
#include "BKE_cloth.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
@@ -5031,6 +5032,145 @@ static void clothModifier_freeData(ModifierData *md)
}
}
/* Collision */
static void collisionModifier_initData(ModifierData *md)
{
CollisionModifierData *collmd = (CollisionModifierData*) md;
collmd->x = NULL;
collmd->xnew = NULL;
collmd->current_x = NULL;
collmd->current_xnew = NULL;
collmd->current_v = NULL;
collmd->time = -1;
collmd->numverts = 0;
collmd->tree = NULL;
}
static void collisionModifier_freeData(ModifierData *md)
{
CollisionModifierData *collmd = (CollisionModifierData*) md;
if (collmd)
{
if(collmd->tree)
bvh_free(collmd->tree);
if(collmd->x)
MEM_freeN(collmd->x);
if(collmd->xnew)
MEM_freeN(collmd->xnew);
if(collmd->current_x)
MEM_freeN(collmd->current_x);
if(collmd->current_xnew)
MEM_freeN(collmd->current_xnew);
if(collmd->current_v)
MEM_freeN(collmd->current_v);
collmd->x = NULL;
collmd->xnew = NULL;
collmd->current_x = NULL;
collmd->current_xnew = NULL;
collmd->current_v = NULL;
collmd->time = -1;
collmd->numverts = 0;
collmd->tree = NULL;
}
}
static int collisionModifier_dependsOnTime(ModifierData *md)
{
return 1;
}
static void collisionModifier_deformVerts(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts)
{
CollisionModifierData *collmd = (CollisionModifierData*) md;
DerivedMesh *dm = NULL;
float current_time = 0;
unsigned int numverts = 0, i = 0;
MVert *tempVert = NULL;
// if possible use/create DerivedMesh
if(derivedData) dm = CDDM_copy(derivedData);
else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
if(!ob->pd)
{
printf("collisionModifier_deformVerts: Should not happen!\n");
return;
}
if(dm)
{
CDDM_apply_vert_coords(dm, vertexCos);
CDDM_calc_normals(dm);
current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
if(current_time > collmd->time)
{
numverts = dm->getNumVerts ( dm );
// check if mesh has changed
if(collmd->x && (numverts != collmd->numverts))
collisionModifier_freeData((ModifierData *)collmd);
if(collmd->time == -1) // first time
{
collmd->x = dm->dupVertArray(dm); // frame start position
for ( i = 0; i < numverts; i++ )
{
// we save global positions
Mat4MulVecfl ( ob->obmat, collmd->x[i].co );
}
collmd->xnew = MEM_dupallocN(collmd->x); // frame end position
collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame
collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
collmd->numverts = numverts;
// TODO: epsilon
// create bounding box hierarchy
collmd->tree = bvh_build_from_mvert(dm->getFaceArray(dm), dm->getNumFaces(dm), collmd->current_x, numverts, ob->pd->pdef_sbift);
}
else if(numverts == collmd->numverts)
{
// put positions to old positions
tempVert = collmd->x;
collmd->x = collmd->xnew;
collmd->xnew = tempVert;
memcpy(collmd->xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
for ( i = 0; i < numverts; i++ )
{
// we save global positions
Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co );
}
memcpy(collmd->current_xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
memcpy(collmd->current_x, dm->getVertArray(dm), numverts*sizeof(MVert));
// recalc static bounding boxes
bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0);
}
collmd->time = current_time;
}
}
if(dm)
dm->release(dm);
}
/* Boolean */
static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
@@ -6855,6 +6995,16 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
// mti->copyData = clothModifier_copyData;
mti->deformVerts = clothModifier_deformVerts;
mti->updateDepgraph = clothModifier_updateDepgraph;
mti = INIT_TYPE(Collision);
mti->type = eModifierTypeType_OnlyDeform;
mti->initData = collisionModifier_initData;
mti->flags = eModifierTypeFlag_AcceptsMesh
| eModifierTypeFlag_RequiresOriginalData;
mti->dependsOnTime = collisionModifier_dependsOnTime;
mti->freeData = collisionModifier_freeData;
mti->deformVerts = collisionModifier_deformVerts;
// mti->copyData = collisionModifier_copyData;
mti = INIT_TYPE(Boolean);
mti->type = eModifierTypeType_Nonconstructive;

View File

@@ -106,7 +106,7 @@ typedef struct SimulationSettings
float bending; /* Flexion spring stiffness. */
float sim_time;
int flags; /* flags, see CSIMSETT_FLAGS enum above. */
short solver_type; /* which solver should be used? */
short solver_type; /* which solver should be used? txold */
short pad2;
float maxgoal; /* see SB */
float eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/

View File

@@ -3184,7 +3184,7 @@ static void object_panel_deflection(Object *ob)
PartDeflect *pd= ob->pd;
but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
// uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
if(pd->deflect) {
uiDefBut(block, LABEL, 0, "Particles", 160,140,75,20, NULL, 0.0, 0, 0, 0, "");
@@ -4928,7 +4928,7 @@ static void object_panel_cloth(Object *ob)
Cloth *cloth = clmd->clothObject;
int defCount;
char *clvg1, *clvg2;
char clmvg [] = "Mass Vertex Group%t|None%x0|";
char clmvg [] = "Weight Paint Groups%t|";
val2=0;
@@ -4938,12 +4938,12 @@ static void object_panel_cloth(Object *ob)
uiClearButLock();
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms.structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure");
uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility");
uiDefButI(block, NUM, B_CLOTH_RENEW, "Steps per Frame:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)");
uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms.bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)");
uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms.stepsPerFrame, 1.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms.Cdis, 0.0, 10.0, 10, 0, "Spring damping");
uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms.Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down");
uiBlockEndAlign(block);
uiClearButLock();
@@ -4959,7 +4959,7 @@ static void object_panel_cloth(Object *ob)
/* GOAL STUFF */
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Pinning of cloth", 10,70,150,20, &clmd->sim_parms.flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
if (clmd->sim_parms.flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
{
if(ob->type==OB_MESH)
@@ -4977,26 +4977,15 @@ static void object_panel_cloth(Object *ob)
{
clmd->sim_parms.vgroup_mass = 0;
}
else
if(!clmd->sim_parms.vgroup_mass)
clmd->sim_parms.vgroup_mass = 1;
sprintf (clvg2, "%s%s", clmvg, clvg1);
uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 140,70,20,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,70,150,20, &clmd->sim_parms.vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
MEM_freeN (clvg1);
MEM_freeN (clvg2);
if(clmd->sim_parms.vgroup_mass)
{
bDeformGroup *defGroup = BLI_findlink(&ob->defbase, clmd->sim_parms.vgroup_mass-1);
if(defGroup)
uiDefBut(block, BUT, B_DIFF, defGroup->name, 160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
else
uiDefBut(block, BUT, B_DIFF, "(no group)", 160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore");
uiDefIconBut(block, BUT, B_CLOTH_DEL_VG, ICON_X, 290,70,20,20, 0, 0, 0, 0, 0, "Disable use of vertex group");
}
else
uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
}
else
{
@@ -5004,10 +4993,13 @@ static void object_panel_cloth(Object *ob)
uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:", 160,70,150,20, &clmd->sim_parms.defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
}
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, "Pin Stiff:", 10,50,150,20, &clmd->sim_parms.goalspring, 0.0, 500.0, 10, 0, "Pin (vertex target position) spring stiffness");
/*
// nobody is changing these ones anyway
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");
*/
}
uiBlockEndAlign(block);