This commit is contained in:
Daniel Genrich
2007-11-27 13:25:07 +00:00
15 changed files with 151 additions and 105 deletions

View File

@@ -68,6 +68,7 @@ typedef struct ClothVertex {
float impulse[3]; /* used in collision.c */
unsigned int impulse_count; /* same as above */
float collball;
char octantflag;
} ClothVertex;
typedef struct ClothSpring {

View File

@@ -125,7 +125,7 @@ static void cloth_to_object (Object *ob, DerivedMesh *dm, ClothModifierData *cl
static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr);
static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr);
int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm );
int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup);
/******************************************************************************
*
@@ -160,7 +160,7 @@ void cloth_init (ClothModifierData *clmd)
clmd->coll_parms->friction = 10.0;
clmd->coll_parms->loop_count = 1;
clmd->coll_parms->epsilon = 0.01;
clmd->coll_parms->selfepsilon = 0.1;
clmd->coll_parms->selfepsilon = 0.49;
/* These defaults are copied from softbody.c's
* softbody_calc_forces() function.
@@ -884,7 +884,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
VECCOPY ( clmd->clothObject->verts [i].impulse, tnull );
}
if (!cloth_build_springs (clmd->clothObject, dm) )
if (!cloth_build_springs (clmd, dm) )
{
modifier_setError (&(clmd->modifier), "Can't build springs.");
return 0;
@@ -1035,11 +1035,12 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in
return 0;
}
int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm )
int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
{
Cloth *cloth = clmd->clothObject;
ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0;
unsigned int i = 0, j = 0;
unsigned int i = 0, j = 0, akku_count;
unsigned int numverts = dm->getNumVerts ( dm );
unsigned int numedges = dm->getNumEdges ( dm );
unsigned int numfaces = dm->getNumFaces ( dm );
@@ -1049,7 +1050,7 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm )
LinkNode **edgelist = NULL;
EdgeHash *edgehash = NULL;
LinkNode *search = NULL, *search2 = NULL;
float temp[3];
float temp[3], akku, min, max;
LinkNode *node = NULL, *node2 = NULL;
// error handling
@@ -1096,9 +1097,14 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm )
// calc collision balls *slow*
// better: use precalculated list with O(1) index access to all springs of a vertex
// missing for structural since it's not needed for building bending springs
/*
for ( i = 0; i < numverts; i++ )
{
akku_count = 0;
akku = 0.0;
cloth->verts[i].collball=0;
min = 1e22f;
max = -1e22f;
search = cloth->springs;
for ( j = 0; j < struct_springs; j++ )
{
@@ -1109,14 +1115,19 @@ int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm )
if((tspring->ij == i) || (tspring->kl == i))
{
akku += bs->len;
akku_count++,
min = MIN2(bs->len,min);
max = MAX2(bs->len,max);
akku += spring->restlen;
akku_count++;
min = MIN2(spring->restlen,min);
max = MAX2(spring->restlen,max);
}
}
if (akku_count > 0) {
cloth->verts[i].collball = akku/(float)akku_count*clmd->coll_parms->selfepsilon;
}
else cloth->verts[i].collball=0;
}
*/
// shear springs
for ( i = 0; i < numfaces; i++ )
{

View File

@@ -2235,76 +2235,81 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
collisions = 1;
count = 0;
current_x = cloth->current_x; // needed for openMP
/*
#pragma omp parallel for private(i,j, collisions) shared(current_x)
for(count = 0; count < 6; count++)
// #pragma omp parallel for private(i,j, collisions) shared(current_x)
// for ( count = 0; count < 6; count++ )
{
collisions = 0;
for(i = 0; i < cloth->numverts; i++)
{
for(j = i + 1; j < cloth->numverts; j++)
{
float temp[3];
float length = 0;
float mindistance = cloth->selftree->epsilon;
collisions = 0;
for ( i = 0; i < cloth->numverts; i++ )
{
float mindistance1 = cloth->verts[i].collball;
for ( j = i + 1; j < cloth->numverts; j++ )
{
float temp[3];
float length = 0;
float mindistance2 = cloth->verts[j].collball;
if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
{
if ( ( cloth->verts [i].goal >= SOFTGOALSNAP )
&& ( cloth->verts [j].goal >= SOFTGOALSNAP ) )
{
continue;
}
}
// check for adjacent points
if ( BLI_edgehash_haskey ( cloth->edgehash, i, j ) )
{
continue;
}
VECSUB ( temp, current_x[i], current_x[j] );
length = Normalize ( temp );
if ( length < ((mindistance1 + mindistance2)) )
{
float correction = ((mindistance1 + mindistance2)) - length;
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
{
if((cloth->verts [i].goal >= SOFTGOALSNAP)
&& (cloth->verts [j].goal >= SOFTGOALSNAP))
{
continue;
}
}
// check for adjacent points
if(BLI_edgehash_haskey ( cloth->edgehash, i, j ))
{
continue;
}
VECSUB(temp, current_x[i], current_x[j]);
length = Normalize(temp);
if(length < mindistance)
{
float correction = mindistance - length;
if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [i].goal >= SOFTGOALSNAP))
{
VecMulf(temp, -correction);
VECADD(current_x[j], current_x[j], temp);
}
else if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (cloth->verts [j].goal >= SOFTGOALSNAP))
{
VecMulf(temp, correction);
VECADD(current_x[i], current_x[i], temp);
}
else
{
VecMulf(temp, -correction*0.5);
VECADD(current_x[j], current_x[j], temp);
VECSUB(current_x[i], current_x[i], temp);
}
collisions = 1;
}
}
}
}
printf("correction: %f\n", correction);
if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) && ( cloth->verts [i].goal >= SOFTGOALSNAP ) )
{
VecMulf ( temp, -correction );
VECADD ( current_x[j], current_x[j], temp );
}
else if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) && ( cloth->verts [j].goal >= SOFTGOALSNAP ) )
{
VecMulf ( temp, correction );
VECADD ( current_x[i], current_x[i], temp );
}
else
{
VecMulf ( temp, -correction*0.5 );
VECADD ( current_x[j], current_x[j], temp );
VECSUB ( current_x[i], current_x[i], temp );
}
collisions = 1;
}
}
}
}
//////////////////////////////////////////////
// SELFCOLLISIONS: update velocities
//////////////////////////////////////////////
for(i = 0; i < cloth->numverts; i++)
for ( i = 0; i < cloth->numverts; i++ )
{
VECSUB(cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i]);
}
VECSUB ( cloth->current_v[i], cloth->current_x[i], cloth->current_xold[i] );
}
//////////////////////////////////////////////
*/
return 1;
}

View File

@@ -5342,7 +5342,7 @@ static void particleSystemModifier_deformVerts(
ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
ParticleSystem * psys=0;
int totvert=0,totedge=0,totface=0,needsFree=0;
if(ob->particlesystem.first)
psys=psmd->psys;
else
@@ -5417,8 +5417,6 @@ static void particleSystemModifier_deformVerts(
if(psmd->flag & eParticleSystemFlag_Loaded)
psmd->flag &= ~eParticleSystemFlag_Loaded;
else{
/* TODO PARTICLE - Added this so changing subsurf under hair updates it
should it be done elsewhere? - Campbell */
psys->recalc |= PSYS_RECALC_HAIR;
psys->recalc |= PSYS_DISTR;
psmd->flag |= eParticleSystemFlag_DM_changed;
@@ -5432,6 +5430,9 @@ static void particleSystemModifier_deformVerts(
}
}
/* disabled particles in editmode for now, until support for proper derivedmesh
* updates is coded */
#if 0
static void particleSystemModifier_deformVertsEM(
ModifierData *md, Object *ob, EditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
@@ -5444,6 +5445,7 @@ static void particleSystemModifier_deformVertsEM(
if(!derivedData) dm->release(dm);
}
#endif
/* Particle Instance */
static void particleInstanceModifier_initData(ModifierData *md)
@@ -7037,13 +7039,18 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti = INIT_TYPE(ParticleSystem);
mti->type = eModifierTypeType_OnlyDeform;
mti->flags = eModifierTypeFlag_AcceptsMesh
|eModifierTypeFlag_SupportsEditmode
| eModifierTypeFlag_SupportsMapping;
#if 0
| eModifierTypeFlag_SupportsEditmode;
|eModifierTypeFlag_EnableInEditmode;
#endif
mti->initData = particleSystemModifier_initData;
mti->freeData = particleSystemModifier_freeData;
mti->copyData = particleSystemModifier_copyData;
mti->deformVerts = particleSystemModifier_deformVerts;
#if 0
mti->deformVertsEM = particleSystemModifier_deformVertsEM;
#endif
mti->requiredDataMask = particleSystemModifier_requiredDataMask;
mti = INIT_TYPE(ParticleInstance);
@@ -7123,9 +7130,8 @@ int modifier_supportsMapping(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
return ( (mti->flags & eModifierTypeFlag_SupportsEditmode) &&
( (mti->type==eModifierTypeType_OnlyDeform ||
(mti->flags & eModifierTypeFlag_SupportsMapping))) );
return (mti->type==eModifierTypeType_OnlyDeform ||
(mti->flags & eModifierTypeFlag_SupportsMapping));
}
ModifierData *modifiers_findByType(Object *ob, ModifierType type)

View File

@@ -583,7 +583,7 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float *
if(osface==NULL || origindex==NULL) {
/* Assume we dont need osface data */
if (index <totface) {
printf("\tNO CD_ORIGSPACE, assuming not needed\n");
//printf("\tNO CD_ORIGSPACE, assuming not needed\n");
return index;
} else {
printf("\tNO CD_ORIGSPACE, error out of range\n");
@@ -645,7 +645,7 @@ void psys_particle_on_dm(Object *ob, DerivedMesh *dm, int from, int index, int i
/* this works for meshes with deform verts only - constructive modifiers wont work properly*/
float temp1[3];
if(index_dmcache == DMCACHE_ISCHILD && index >= dm->getNumFaces(dm)) {
if(index >= dm->getNumFaces(dm)) {
PARTICLE_ERROR(nor, vec);
return;
}

View File

@@ -3832,7 +3832,7 @@ static void dynamics_step(Object *ob, ParticleSystem *psys, ParticleSystemModifi
if(part->phystype==PART_PHYS_BOIDS){
/* create particle tree for fast inter-particle comparisons */
KDTree *tree=BLI_kdtree_new(totpart);
tree=BLI_kdtree_new(totpart);
for(p=0, pa=psys->particles; p<totpart; p++,pa++){
if(pa->flag & (PARS_NO_DISP+PARS_UNEXIST) || pa->alive!=PARS_ALIVE)
continue;
@@ -4006,7 +4006,7 @@ static void hair_step(Object *ob, ParticleSystemModifierData *psmd, ParticleSyst
{
ParticleSettings *part = psys->part;
if(psys->recalc & PSYS_DISTR){
if(psys->recalc & PSYS_DISTR) {
/* need this for changing subsurf levels */
psys_calc_dmfaces(ob, psmd->dm, psys);
}

View File

@@ -778,7 +778,7 @@ static void calculate_collision_balls(Object *ob)
bs = sb->bspring + bp->springs[b-1];
if (bs->order == 1){
akku += bs->len;
akku_count++,
akku_count++;
min = MIN2(bs->len,min);
max = MAX2(bs->len,max);
}

View File

@@ -1755,11 +1755,13 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
return 1;
}
psmd= psys_get_modifier(ob,psys);
if(!(psmd->modifier.mode & eModifierMode_Render))
return 0;
psys->flag|=PSYS_DRAWING;
BLI_srandom(psys->seed);
psmd= psys_get_modifier(ob,psys);
ma= give_render_material(re, ob, part->omat);
@@ -1950,6 +1952,11 @@ static int render_new_particle_system(Render *re, Object *ob, ParticleSystem *ps
r_tilt=2.0f*cpa->rand[2];
/* get orco */
psys_particle_on_emitter(ob, psmd,
(part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,orco,0,0,0);
if(uvco){
layer=psmd->dm->faceData.layers + CustomData_get_layer_index(&psmd->dm->faceData,CD_MFACE);

View File

@@ -1606,6 +1606,12 @@ static void modifiers_bindMeshDeform(void *ob_v, void *md_v)
else if(ob->type == OB_LATTICE) {
lattice_calc_modifiers(ob);
}
else if(ob->type==OB_MBALL) {
makeDispListMBall(ob);
}
else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
makeDispListCurveTypes(ob, 0);
}
mmd->needbind= 0;
mmd->modifier.mode= mode;
@@ -1619,6 +1625,16 @@ void modifiers_explodeFacepa(void *arg1, void *arg2)
emd->flag |= eExplodeFlag_CalcFaces;
}
static void modifiers_psysEnable(void *ob_v, void *md_v)
{
ParticleSystemModifierData *psmd = (ParticleSystemModifierData*) md_v;
if(psmd->modifier.mode & eModifierMode_Realtime)
psmd->psys->flag |= PSYS_ENABLED;
else
psmd->psys->flag &= ~PSYS_ENABLED;
}
static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco, int *yco, int index, int cageIndex, int lastCageIndex)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -1657,7 +1673,9 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
/* Softbody not allowed in this situation, enforce! */
if ((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) {
uiDefIconButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, ICON_SCENE, x+10+buttonWidth-60, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+10+buttonWidth-40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+10+buttonWidth-40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
if (md->type==eModifierType_ParticleSystem)
uiButSetFunc(but, modifiers_psysEnable, ob, md);
if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
uiDefIconButBitI(block, TOG, eModifierMode_Editmode, B_MODIFIER_RECALC, VICON_EDIT, x+10+buttonWidth-20, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
}

View File

@@ -3768,7 +3768,7 @@ static void object_panel_particle_extra(Object *ob)
butx+=butw;
uiDefButS(block, MENU, B_PART_REDRAW, menustr, butx,buty,buth,buth, psys->vgroup+vgnum, 0, defCount, 0, 0, "Browses available vertex groups");
but= uiDefButS(block, MENU, B_PART_REDRAW, menustr, butx,buty,buth,buth, psys->vgroup+vgnum, 0, defCount, 0, 0, "Browses available vertex groups");
uiButSetFunc(but, particle_set_vg, (void *)ob, (void *)(&vgnum));
MEM_freeN (menustr);
@@ -4839,7 +4839,7 @@ static void object_panel_cloth_III(Object *ob)
// uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 10,140,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in");
uiDefBut(block, LABEL, 0, "",160,140,150,20, NULL, 0.0, 0, 0, 0, "");
uiDefButF(block, NUM, B_CLOTH_RENEW, "Selfcoll balls:", 10,120,150,20, &clmd->coll_parms->selfepsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between two selfcollision points");
uiDefButF(block, NUM, B_CLOTH_RENEW, "Selfcoll balls:", 10,120,150,20, &clmd->coll_parms->selfepsilon, 0.001f, 1.0, 0.49f, 0, "Minimum distance between two selfcollision points");
}
else
uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, "");
@@ -4888,7 +4888,7 @@ void particle_panels()
ob=OBACT;
if(ob) {
if(ob && ob->type==OB_MESH) {
object_panel_particle_system(ob);
psys=psys_get_current(ob);

View File

@@ -3859,8 +3859,8 @@ static uiBlock *strand_menu(void *mat_v)
uiDefButBitI(block, TOG, MA_TANGENT_STR, 0, "Use Tangent Shading", 10,90,115,20, &(ma->mode), 0, 0, 0, 0, "Uses direction of strands as normal for tangent-shading");
uiDefButBitI(block, TOG, MA_STR_B_UNITS, 0, "Use Blender Units", 125,90,115,20, &(ma->mode), 0, 0, 0, 0, "Use actual Blender units for widths instead of pixels");
if(ma->mode & MA_STR_B_UNITS){
uiDefButF(block, NUMSLI, 0, "Start ", 10, 70, 230,20, &ma->strand_sta, 0.01, 20.0, 2, 0, "Start size of strands in Blender units");
uiDefButF(block, NUMSLI, 0, "End ", 10, 50, 230,20, &ma->strand_end, 0.01, 10.0, 2, 0, "End size of strands in Blender units");
uiDefButF(block, NUMSLI, 0, "Start ", 10, 70, 230,20, &ma->strand_sta, 0.0001, 2.0, 2, 0, "Start size of strands in Blender units");
uiDefButF(block, NUMSLI, 0, "End ", 10, 50, 230,20, &ma->strand_end, 0.0001, 1.0, 2, 0, "End size of strands in Blender units");
}
else{
uiDefButF(block, NUMSLI, 0, "Start ", 10, 70, 230,20, &ma->strand_sta, 0.25, 20.0, 2, 0, "Start size of strands in pixels");

View File

@@ -3407,10 +3407,9 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys)
/* 6. */
glGetIntegerv(GL_POLYGON_MODE, polygonmode);
glDisableClientState(GL_NORMAL_ARRAY);
if(draw_as != PART_DRAW_CIRC){
glDisableClientState(GL_NORMAL_ARRAY);
if(draw_as==PART_DRAW_PATH){
ParticleCacheKey **cache, *path;
float *cd2=0,*cdata2=0;
@@ -5038,7 +5037,7 @@ void draw_object(Base *base, int flag)
if(ob->pd && ob->pd->forcefield) draw_forcefield(ob);
/* code for new particle system */
if(warning_recursive==0 && (flag & DRAW_PICKING)==0){
if(warning_recursive==0 && (flag & DRAW_PICKING)==0 && ob!=G.obedit){
glDepthMask(GL_FALSE);
if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); /* for visibility, also while wpaint */
if(ob->particlesystem.first) {

View File

@@ -2134,7 +2134,7 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
/* warning, returns the derived mesh face */
#if EXPERIMENTAL_DEFORM_ONLY_PAINTING
if(psys_intersect_dm(ob,dm,0,co1,co2,&min_d,&add_pars[n].num,add_pars[n].fuv,0,0,0,0)) {
add_pars[n].num_dmcache= psys_particle_dm_face_lookup(ob,dm,add_pars[n].num,add_pars[n].fuv,NULL);
add_pars[n].num_dmcache= psys_particle_dm_face_lookup(ob,psmd->dm,add_pars[n].num,add_pars[n].fuv,NULL);
n++;
}
#else
@@ -2365,7 +2365,7 @@ int PE_brush_particles(void)
ParticleSystemModifierData *psmd;
ParticleBrushData *brush;
float vec1[3], vec2[3];
short mval[2], mvalo[2], firsttime = 1, dx, dy, mousebut;
short mval[2], mvalo[2], firsttime = 1, dx, dy;
int selected = 0, flip;
if(!PE_can_edit(psys)) return 0;
@@ -2373,9 +2373,6 @@ int PE_brush_particles(void)
edit = psys->edit;
psmd= psys_get_modifier(ob, psys);
/* check for left mouse / right mouse button select */
if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
else mousebut = L_MOUSE;
flip= (get_qual() == LR_SHIFTKEY);
if(pset->brushtype<0) return 0;
@@ -2387,7 +2384,7 @@ int PE_brush_particles(void)
mval[0] = mvalo[0]; mval[1] = mvalo[1];
while(get_mbut() & mousebut){
while(get_mbut() & L_MOUSE){
bglFlush();
glReadBuffer(GL_BACK);
glDrawBuffer(GL_BACK);

View File

@@ -491,6 +491,8 @@ static void addqueue_ext(short win, unsigned short event, short val, char ascii)
}
else {
BWinEvent evt;
memset(&evt, 0, sizeof(evt));
evt.event= event;
evt.val= val;
evt.ascii= ascii;

View File

@@ -1185,7 +1185,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
/* only swap mouse button for selection, in modes where it is relevant.
* painting/sculpting stays on LEFTMOUSE */
if ( !((G.f & G_SCULPTMODE) || (G.f & G_WEIGHTPAINT) ||
(G.f & G_VERTEXPAINT) || (G.f & G_TEXTUREPAINT)) ||
(G.f & G_VERTEXPAINT) || (G.f & G_TEXTUREPAINT) || (G.f & G_PARTICLEEDIT)) ||
(G.obedit) )
{
if (event==LEFTMOUSE) event = RIGHTMOUSE;