Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJens Ole Wund <bjornmose@gmx.net>2006-10-11 01:49:02 +0400
committerJens Ole Wund <bjornmose@gmx.net>2006-10-11 01:49:02 +0400
commitb6b5cdefa954592f18931425b89d7a60a3810251 (patch)
tree8d31e4707b3e517ed6cac6f670b8da904cfec41f /source
parentbba546e5fbb43e200e8b1eac6597ba3e8c653080 (diff)
some tiny changes to the softbody system
- UI for self collision ball size definition - edge collision mode added (almost a bug fix) volatile test file --> http://www.wund.homepage.t-online.de/hidden/sb_col_must_1_2.blend
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/softbody.c273
-rw-r--r--source/blender/blenlib/BLI_arithb.h1
-rw-r--r--source/blender/blenlib/intern/arithb.c84
-rw-r--r--source/blender/makesdna/DNA_object_force.h8
-rw-r--r--source/blender/src/buttons_object.c8
5 files changed, 337 insertions, 37 deletions
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 4fa7a1bcd23..dba505fbe27 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -82,8 +82,6 @@ variables on the UI for now
#include "BIF_editdeform.h"
-
-
/* ********** soft body engine ******* */
typedef struct BodyPoint {
@@ -98,7 +96,14 @@ typedef struct BodyPoint {
typedef struct BodySpring {
int v1, v2;
float len, strength;
+ float ext_force[3];
+ /* ^^^^^^^^^ for collision now,
+ but could be used for forces depending on orientations
+ such as wind --> project the lenght on the (relative) wind
+ via inner product force -> sin(<v_wind-v_spring,v1-v2>)
+ */
short order;
+ short flag;
} BodySpring;
@@ -109,6 +114,9 @@ typedef struct BodySpring {
#define HEUNWARNLIMIT 1 /* 50 would be fine i think for detecting severe *stiff* stuff */
+#define BSF_INTERSECT 1 /* edge intersects collider face */
+
+
float SoftHeunTol = 1.0f; /* humm .. this should be calculated from sb parameters and sizes */
/* local prototypes */
@@ -184,9 +192,13 @@ typedef struct ccd_Mesh {
MFace *mface;
int savety;
ccdf_minmax *mima;
+ /* Axis Aligned Bounding Box AABB */
float bbmin[3];
float bbmax[3];
-
+ /* Max Ball */
+ float mb_center[3];
+ float mb_radius;
+
}ccd_Mesh;
@@ -344,6 +356,12 @@ ccd_Mesh *ccd_mesh_make(Object *ob, DispListMesh *dm)
pccd_M->bbmax[2] = MAX2(pccd_M->bbmax[2],v[2]+hull);
}
+ /* now we have AABB */
+ /* let's make the balls */
+ pccd_M->mb_center[0] = (pccd_M->bbmin[0] + pccd_M->bbmax[0]) / 2.0f;
+ pccd_M->mb_center[1] = (pccd_M->bbmin[1] + pccd_M->bbmax[1]) / 2.0f;
+ pccd_M->mb_center[2] = (pccd_M->bbmin[2] + pccd_M->bbmax[2]) / 2.0f;
+ pccd_M->mb_radius =VecLenf(pccd_M->mb_center,pccd_M->bbmin);
/* alloc and copy faces*/
pccd_M->mface = MEM_mallocN(sizeof(MFace)*pccd_M->totface,"ccd_Mesh_Faces");
memcpy(pccd_M->mface,dm->mface,sizeof(MFace)*pccd_M->totface);
@@ -707,24 +725,24 @@ static void calculate_collision_balls(Object *ob)
}
if (akku_count > 0) {
- bp->colball = akku/(float)akku_count;
- /* i don't want to taint a "short pad" member in SDNA yet
- so hack alternatives in that way */
- if (sb->colball > 0.0f){
+ if (sb->sbc_mode == 0){
bp->colball=sb->colball;
}
- if (sb->colball == -1.0f){
- bp->colball=max;
+ if (sb->sbc_mode == 1){
+ bp->colball = akku/(float)akku_count*sb->colball;
+ }
+ if (sb->colball == 2){
+ bp->colball=min*sb->colball;
}
- if (sb->colball == -0.1f){
- bp->colball=min;
+ if (sb->colball == 3){
+ bp->colball=max*sb->colball;
}
- if (sb->colball == -1.1f){
- bp->colball = (min + max)/2.0f;
+ if (sb->colball == 4){
+ bp->colball = (min + max)/2.0f*sb->colball;
}
}
else bp->colball=0;
- /* printf("CB %f \n",bp->colball); */
+ /* printf("CB %f \n",bp->colball); */
}/*for bp*/
}
@@ -838,13 +856,193 @@ static void free_softbody_intern(SoftBody *sb)
** since that would only valid for 'slow' moving collision targets and dito particles
*/
-int sb_detect_collisionCached(float opco[3], float facenormal[3], float *damp,
+/* BEGIN the spring external section*/
+
+//#if (0)
+
+int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp,
+ float force[3], unsigned int par_layer,struct Object *vertexowner)
+{
+ Base *base;
+ Object *ob;
+ float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3],aabbmax[3];
+ float t,el;
+ int a, deflected=0;
+
+ aabbmin[0] = MIN2(edge_v1[0],edge_v2[0]);
+ aabbmin[1] = MIN2(edge_v1[1],edge_v2[1]);
+ aabbmin[2] = MIN2(edge_v1[2],edge_v2[2]);
+ aabbmax[0] = MAX2(edge_v1[0],edge_v2[0]);
+ aabbmax[1] = MAX2(edge_v1[1],edge_v2[1]);
+ aabbmax[2] = MAX2(edge_v1[2],edge_v2[2]);
+
+ el = VecLenf(edge_v1,edge_v2);
+
+ base= G.scene->base.first;
+ while (base) {
+ /*Only proceed for mesh object in same layer */
+ if(base->object->type==OB_MESH && (base->lay & par_layer)) {
+ ob= base->object;
+ if((vertexowner) && (ob == vertexowner)){
+ /* if vertexowner is given we don't want to check collision with owner object */
+ base = base->next;
+ continue;
+ }
+
+ /* only with deflecting set */
+ if(ob->pd && ob->pd->deflect) {
+ MFace *mface= NULL;
+ MVert *mvert= NULL;
+ ccdf_minmax *mima= NULL;
+
+ if(ob->sumohandle){
+ ccd_Mesh *ccdm=ob->sumohandle;
+ mface= ccdm->mface;
+ mvert= ccdm->mvert;
+ mima= ccdm->mima;
+ a = ccdm->totface;
+
+ if ((aabbmax[0] < ccdm->bbmin[0]) ||
+ (aabbmax[1] < ccdm->bbmin[1]) ||
+ (aabbmax[2] < ccdm->bbmin[2]) ||
+ (aabbmin[0] > ccdm->bbmax[0]) ||
+ (aabbmin[1] > ccdm->bbmax[1]) ||
+ (aabbmin[2] > ccdm->bbmax[2]) ) {
+ /* boxes dont intersect */
+ base = base->next;
+ continue;
+ }
+
+ }
+ else{
+ /*aye that should be cached*/
+ printf("missing cache error \n");
+ base = base->next;
+ continue;
+ }
+
+
+ /* use mesh*/
+ while (a--) {
+ if (
+ (aabbmax[0] < mima->minx) ||
+ (aabbmin[0] > mima->maxx) ||
+ (aabbmax[1] < mima->miny) ||
+ (aabbmin[1] > mima->maxy) ||
+ (aabbmax[2] < mima->minz) ||
+ (aabbmin[2] > mima->maxz)
+ ) {
+ mface++;
+ mima++;
+ continue;
+ }
+
+
+ if (mvert){
+
+ VECCOPY(nv1,mvert[mface->v1].co);
+ VECCOPY(nv2,mvert[mface->v2].co);
+ VECCOPY(nv3,mvert[mface->v3].co);
+ if (mface->v4){
+ VECCOPY(nv4,mvert[mface->v4].co);
+ }
+ }
+
+
+
+ /* switch origin to be nv2*/
+ VECSUB(edge1, nv1, nv2);
+ VECSUB(edge2, nv3, nv2);
+
+ Crossf(d_nvect, edge2, edge1);
+ Normalise(d_nvect);
+ if ( LineIntersectsTriangle(edge_v1, edge_v2, nv1, nv2, nv3, &t)){
+ float v1[3],v2[3];
+ float intrusiondepth,i1,i2;
+ VECSUB(v1, edge_v1, nv2);
+ VECSUB(v2, edge_v2, nv2);
+ i1 = Inpf(v1,d_nvect);
+ i2 = Inpf(v2,d_nvect);
+ intrusiondepth = -MIN2(i1,i2)/el;
+ Vec3PlusStVec(force,intrusiondepth,d_nvect);
+ *damp=ob->pd->pdef_sbdamp;
+ deflected = 2;
+ }
+ if (mface->v4){ /* quad */
+ /* switch origin to be nv4 */
+ VECSUB(edge1, nv3, nv4);
+ VECSUB(edge2, nv1, nv4);
+
+ Crossf(d_nvect, edge2, edge1);
+ Normalise(d_nvect);
+ if (LineIntersectsTriangle( edge_v1, edge_v2,nv1, nv3, nv4, &t)){
+ float v1[3],v2[3];
+ float intrusiondepth,i1,i2;
+ VECSUB(v1, edge_v1, nv4);
+ VECSUB(v2, edge_v2, nv4);
+ i1 = Inpf(v1,d_nvect);
+ i2 = Inpf(v2,d_nvect);
+ intrusiondepth = -MIN2(i1,i2)/el;
+
+
+ Vec3PlusStVec(force,intrusiondepth,d_nvect);
+ *damp=ob->pd->pdef_sbdamp;
+ deflected = 2;
+ }
+ }
+ mface++;
+ mima++;
+ }/* while a */
+ } /* if(ob->pd && ob->pd->deflect) */
+ }/* if (base->object->type==OB_MESH && (base->lay & par_layer)) { */
+ base = base->next;
+ } /* while (base) */
+ return deflected;
+}
+
+//#endif
+
+
+void scan_for_ext_spring_forces(Object *ob)
+{
+ SoftBody *sb = ob->soft;
+ int a;
+ float damp; /* note, damp is mute here, but might be weight painted in future */
+ float feedback[3];
+ if (sb && sb->totspring){
+ for(a=0; a<sb->totspring; a++) {
+ BodySpring *bs = &sb->bspring[a];
+ bs->ext_force[0]=bs->ext_force[1]=bs->ext_force[2]=0.0f;
+ feedback[0]=feedback[1]=feedback[2]=0.0f;
+ bs->flag &= ~BSF_INTERSECT;
+
+ /* +++ springs colliding */
+ if (bs->order ==1){
+ if ( sb_detect_edge_collisionCached (sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos,
+ &damp,feedback,ob->lay,ob)){
+ VecAddf(bs->ext_force,bs->ext_force,feedback);
+ bs->flag |= BSF_INTERSECT;
+
+ }
+ }
+ /* ---- springs colliding */
+
+ /* +++ springs seeing wind ... n stuff depending on their orientation*/
+ /* nothing here yet, but get the idea */
+ /* --- springs seeing wind */
+
+ }
+ }
+}
+/* END the spring external section*/
+
+int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *damp,
float force[3], unsigned int par_layer,struct Object *vertexowner)
{
Base *base;
Object *ob;
- float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3], dv2[3],
- facedist,n_mag,t,force_mag_norm,minx,miny,minz,maxx,maxy,maxz,
+ float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3],
+ facedist,n_mag,force_mag_norm,minx,miny,minz,maxx,maxy,maxz,
innerfacethickness = -0.5f, outerfacethickness = 0.2f,
ee = 5.0f, ff = 0.1f, fa;
int a, deflected=0;
@@ -909,7 +1107,6 @@ int sb_detect_collisionCached(float opco[3], float facenormal[3], float *damp,
/* use mesh*/
while (a--) {
-
if (
(opco[0] < mima->minx) ||
(opco[0] > mima->maxx) ||
@@ -945,10 +1142,11 @@ int sb_detect_collisionCached(float opco[3], float facenormal[3], float *damp,
facedist = Inpf(dv1,d_nvect);
if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){
- dv2[0] = opco[0] - 2.0f*facedist*d_nvect[0];
- dv2[1] = opco[1] - 2.0f*facedist*d_nvect[1];
- dv2[2] = opco[2] - 2.0f*facedist*d_nvect[2];
- if ( LineIntersectsTriangle( opco, dv2, nv1, nv2, nv3, &t)){
+// dv2[0] = opco[0] - 2.0f*facedist*d_nvect[0];
+// dv2[1] = opco[1] - 2.0f*facedist*d_nvect[1];
+// dv2[2] = opco[2] - 2.0f*facedist*d_nvect[2];
+// if ( LineIntersectsTriangle( opco, dv2, nv1, nv2, nv3, &t)){
+ if (point_in_tri_prism(opco, nv1, nv2, nv3) ){
force_mag_norm =(float)exp(-ee*facedist);
if (facedist > outerfacethickness*ff)
force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
@@ -968,10 +1166,11 @@ int sb_detect_collisionCached(float opco[3], float facenormal[3], float *damp,
facedist = Inpf(dv1,d_nvect);
if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){
- dv2[0] = opco[0] - 2.0f*facedist*d_nvect[0];
- dv2[1] = opco[1] - 2.0f*facedist*d_nvect[1];
- dv2[2] = opco[2] - 2.0f*facedist*d_nvect[2];
- if (LineIntersectsTriangle( opco, dv2, nv1, nv3, nv4, &t)){
+// dv2[0] = opco[0] - 2.0f*facedist*d_nvect[0];
+// dv2[1] = opco[1] - 2.0f*facedist*d_nvect[1];
+// dv2[2] = opco[2] - 2.0f*facedist*d_nvect[2];
+// if (LineIntersectsTriangle( opco, dv2, nv1, nv3, nv4, &t)){
+ if (point_in_tri_prism(opco, nv1, nv3, nv4) ){
force_mag_norm =(float)exp(-ee*facedist);
if (facedist > outerfacethickness*ff)
force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
@@ -1004,12 +1203,11 @@ static void Vec3PlusStVec(float *v, float s, float *v1)
static int sb_deflect_face(Object *ob,float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *force,float *cf)
{
- float s_actpos[3], s_futurepos[3];
+ float s_actpos[3];
int deflected;
VECCOPY(s_actpos,actpos);
- if(futurepos) VECCOPY(s_futurepos,futurepos);
- deflected= sb_detect_collisionCached(s_actpos, facenormal, cf, force , ob->lay, ob);
+ deflected= sb_detect_vertex_collisionCached(s_actpos, facenormal, cf, force , ob->lay, ob);
return(deflected);
}
@@ -1039,7 +1237,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
ListBase *do_effector;
float iks, ks, kd, gravity, actspringlen, forcefactor, sd[3];
float fieldfactor = 1000.0f, windfactor = 250.0f;
- int a, b, do_deflector,do_selfcollision;
+ int a, b, do_deflector,do_selfcollision,do_springcollision;
/* clear forces */
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
@@ -1052,11 +1250,15 @@ static void softbody_calc_forces(Object *ob, float forcetime)
do_deflector= is_there_deflection(ob->lay);
do_effector= pdInitEffectors(ob,NULL);
do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
-
+ do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
bproot= sb->bpoint; /* need this for proper spring addressing */
+
+
+ if (do_springcollision) scan_for_ext_spring_forces(ob);
+
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
/* naive ball self collision */
/* needs to be done if goal snaps or not */
@@ -1085,7 +1287,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
}
if (!attached){
/* would need another UI parameter defining fricton on self contact */
- float ccfriction = 0.05;
+ float ccfriction = 0.05f;
float f = tune/(distance) + tune/(compare*compare)*distance - 2.0f*tune/compare ;
Vec3PlusStVec(bp->force,f,def);
if (bp->contactfrict == 0.0f) bp->contactfrict = ccfriction*compare/distance;
@@ -1200,6 +1402,13 @@ static void softbody_calc_forces(Object *ob, float forcetime)
if (sb->bspring){ /* spring list exists at all ? */
for(b=bp->nofsprings;b>0;b--){
bs = sb->bspring + bp->springs[b-1];
+ if (do_springcollision){
+ VecAddf(bp->force,bp->force,bs->ext_force);
+ if (bs->flag & BSF_INTERSECT)
+ bp->contactfrict = 0.9f; /* another ad hoc magic */
+
+ }
+
if (( (sb->totpoint-a) == bs->v1) ){
actspringlen= VecLenf( (bproot+bs->v2)->pos, bp->pos);
VecSubf(sd,(bproot+bs->v2)->pos, bp->pos);
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index bb2c7f0ec83..c509e2752da 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -891,6 +891,7 @@ void tubemap(float x, float y, float z, float *u, float *v);
void spheremap(float x, float y, float z, float *u, float *v);
int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda);
+int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3]);
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index 40cf72f4242..9053db49aec 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -2942,9 +2942,6 @@ void mul_v3_v3m4(float *v1, float *v2, float mat[][4])
/* moved from effect.c
test if the line starting at p1 ending at p2 intersects the triangle v0..v2
return non zero if it does
-
- wild guess .. says did not check the math since i don't need it
- and if (it intersects) lambda returns intersection = p1 + lambda(p1-p2)
*/
int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda)
{
@@ -2976,3 +2973,84 @@ int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], f
return 1;
}
+
+/*
+find closest point to p on line through l1,l2
+and return lambda, where (0 <= lambda <= 1) when cp is in the line segement l1,l2
+*/
+float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3])
+{
+ float h[3],u[3],lambda;
+ VecSubf(u, l2, l1);
+ VecSubf(h, p, l1);
+ lambda =Inpf(u,h)/Inpf(u,u);
+ cp[0] = l1[0] + u[0] * lambda;
+ cp[1] = l1[1] + u[1] * lambda;
+ cp[2] = l1[2] + u[2] * lambda;
+ return lambda;
+}
+/* little sister we only need to know lambda */
+float lambda_cp_line(float p[3], float l1[3], float l2[3])
+{
+ float h[3],u[3];
+ VecSubf(u, l2, l1);
+ VecSubf(h, p, l1);
+ return(Inpf(u,h)/Inpf(u,u));
+}
+
+
+
+int point_in_slice(float p[3], float v1[3], float l1[3], float l2[3])
+{
+/*
+what is a slice ?
+some maths:
+a line including l1,l2 and a point not on the line
+define a subset of R3 delimeted by planes parallel to the line and orthogonal
+to the (point --> line) distance vector,one plane on the line one on the point,
+the room inside usually is rather small compared to R3 though still infinte
+useful for restricting (speeding up) searches
+e.g. all points of triangular prism are within the intersection of 3 'slices'
+onother trivial case : cube
+but see a 'spat' which is a deformed cube with paired parallel planes needs only 3 slices too
+*/
+float h,rp[3],cp[3],q[3];
+
+lambda_cp_line_ex(v1,l1,l2,cp);
+VecSubf(q,cp,v1);
+
+VecSubf(rp,p,v1);
+h=Inpf(q,rp)/Inpf(q,q);
+if (h < 0.0f || h > 1.0f) return 0;
+return 1;
+}
+
+/*adult sister defining the slice planes by the origin and the normal
+NOTE |normal| may not be 1 but defining the thickness of the slice*/
+int point_in_slice_as(float p[3],float origin[3],float normal[3])
+{
+float h,rp[3];
+VecSubf(rp,p,origin);
+h=Inpf(normal,rp)/Inpf(normal,normal);
+if (h < 0.0f || h > 1.0f) return 0;
+return 1;
+}
+
+/*mama (knowing the squared lenght of the normal)*/
+int point_in_slice_m(float p[3],float origin[3],float normal[3],float lns)
+{
+float h,rp[3];
+VecSubf(rp,p,origin);
+h=Inpf(normal,rp)/lns;
+if (h < 0.0f || h > 1.0f) return 0;
+return 1;
+}
+
+
+int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3])
+{
+if(!point_in_slice(p,v1,v2,v3)) return 0;
+if(!point_in_slice(p,v2,v3,v1)) return 0;
+if(!point_in_slice(p,v3,v1,v2)) return 0;
+return 1;
+} \ No newline at end of file
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index 4af5c356a30..881cbf9565e 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -98,7 +98,12 @@ typedef struct SoftBody {
SBVertex **keys; /* array of size totpointkey */
int totpointkey, totkey; /* if totpointkey != totpoint or totkey!- (efra-sfra)/interval -> free keys */
float secondspring;
- float colball; /* fixed collision ball zize if > 0 */
+ float colball; /* fixed collision ball size if > 0 */
+ float coldamp; /* cooling down collision response */
+ float fpad1; /* cooling down collision response */
+ short sbc_mode;
+ short pad3,pad4,pad5;
+
} SoftBody;
/* pd->forcefield: Effector Fields types */
@@ -125,6 +130,7 @@ typedef struct SoftBody {
#define OB_SB_RESET 256
#define OB_SB_SELF 512
#define OB_SB_COLLISIONSET 1024
+#define OB_SB_EDGECOLL 2048
#ifdef __cplusplus
}
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index a858bcf4ce2..94ce4eda1e0 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -2323,6 +2323,12 @@ static void object_softbodies(Object *ob)
if ((ob->type==OB_MESH) /*may be other types will come*/) {
uiDefButBitS(block, TOG, OB_SB_SELF, B_SOFTBODY_CHANGE, "Self Collision", 10,170,90,20, &ob->softflag, 0, 0, 0, 0, "enable naive vertex ball self collision");
uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Ball Size:", 110,170,170,20, &sb->colball, -10.0, 10.0, 10, 0, "col. ball size ==0 average spring lenght, >0 set collision ball manual, -1.0 max, -0.1 min ,-1.1 (min+max)/2");
+ uiDefButS(block, ROW, B_DIFF, "Man",10,150,60,20, &sb->sbc_mode, 4.0,(float)0, 0, 0, "Manual adjust");
+ uiDefButS(block, ROW, B_DIFF, "Av",70,150,60,20, &sb->sbc_mode, 4.0,(float)1, 0, 0, "Average Spring lenght * Ball Size");
+ uiDefButS(block, ROW, B_DIFF, "Min",130,150,60,20, &sb->sbc_mode, 4.0,(float)2, 0, 0, "Minimal Spring lenght * Ball Size");
+ uiDefButS(block, ROW, B_DIFF, "Max",190,150,60,20, &sb->sbc_mode, 4.0,(float)3, 0, 0, "Maximal Spring lenght * Ball Size");
+ uiDefButS(block, ROW, B_DIFF, "AvMiMa",250,150,60,20, &sb->sbc_mode, 4.0,(float)4, 0, 0, "(Min+Max)/2 * Ball Size");
+
}
/* OTHER OBJECTS COLLISION STUFF */
if (ob->type==OB_MESH){
@@ -2387,7 +2393,7 @@ static void object_softbodies(Object *ob)
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges", 10,30,90,20, &ob->softflag, 0, 0, 0, 0, "Use Edges as springs");
uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads", 110,30,90,20, &ob->softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
- /* uiDefButBitS(block, TOG, OB_SB_SELF, B_DIFF, "Self Collision", 220,30,90,20, &ob->softflag, 0, 0, 0, 0, ""); */
+ uiDefButBitS(block, TOG, OB_SB_EDGECOLL, B_DIFF, "Edge Collision", 220,30,90,20, &ob->softflag, 0, 0, 0, 0, "Edge collide too");
uiDefButF(block, NUM, B_DIFF, "E Stiff:", 10,10,150,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness");
uiDefButF(block, NUM, B_DIFF, "E Damp:", 160,10,150,20, &sb->infrict, 0.0, 50.0, 10, 0, "Edge spring friction");
uiBlockEndAlign(block);