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
diff options
context:
space:
mode:
authorJens Ole Wund <bjornmose@gmx.net>2005-06-06 22:52:07 +0400
committerJens Ole Wund <bjornmose@gmx.net>2005-06-06 22:52:07 +0400
commit91b5992b49f243153a326cb8bbd676830baaada9 (patch)
tree87cff30d523a1f234b8978d45fccc4736a39d260
parent9abdd362b7e109f3268148576e0f63c3bac30a04 (diff)
Fix for # 2655
Now triangles and quads of _any_ shape collide nicly with softbodies. Some tricks don't work in a non euclidian geometry ! Had to brush up that dusty knowlege a bit :) thanks efbie & ton
-rw-r--r--source/blender/blenkernel/intern/effect.c189
1 files changed, 83 insertions, 106 deletions
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index ac28caec12b..dc2594079f2 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -1519,8 +1519,8 @@ int object_wave(Object *ob)
}
int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
- float facenormal[3], float *damp, float force[3], int mode,
- float cur_time, unsigned int par_layer,struct Object *vertexowner)
+ float facenormal[3], float *damp, float force[3], int mode,
+ float cur_time, unsigned int par_layer,struct Object *vertexowner)
{
Base *base;
Object *ob, *deflection_object = NULL;
@@ -1534,17 +1534,16 @@ int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
int a, deflected=0, deflected_now=0;
short cur_frame;
int d_object=0, d_face=0, ds_object=0, ds_face=0;
-
-// i'm going to rearrange it to declaration rules when WIP is finished (BM)
- float u,v,len_u,len_v;
+
+ // i'm going to rearrange it to declaration rules when WIP is finished (BM)
float innerfacethickness = -0.5f;
float outerfacethickness = 0.2f;
float ee = 5.0f;
float ff = 0.1f;
float fa;
-
+
min_t = 200000;
-
+
/* The first part of the code, finding the first intersected face*/
base= G.scene->base.first;
while (base) {
@@ -1552,27 +1551,27 @@ int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
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 */
+ /* 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) {
def_mesh= ob->data;
-
+
d_object = d_object + 1;
-
+
d_face = d_face + 1;
mface= def_mesh->mface;
a = def_mesh->totface;
-/* need to have user control for that since it depends on model scale */
+ /* need to have user control for that since it depends on model scale */
innerfacethickness =-ob->pd->pdef_sbift;
outerfacethickness =ob->pd->pdef_sboft;
- fa = (ff*outerfacethickness-outerfacethickness);
- fa *= fa;
- fa = 1.0f/fa;
+ fa = (ff*outerfacethickness-outerfacethickness);
+ fa *= fa;
+ fa = 1.0f/fa;
if(ob->parent==NULL && ob->ipo==NULL) { // static
if(ob->sumohandle==NULL) cache_object_vertices(ob);
@@ -1593,11 +1592,11 @@ int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
obloc[2] = ob->obmat[3][2];
/* not cachable */
vcache= NULL;
-
+
}
while (a--) {
-
+
if(vcache) {
v1= vcache+ 3*(mface->v1);
VECCOPY(nv1, v1);
@@ -1614,18 +1613,18 @@ int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
v2= (def_mesh->mvert+(mface->v2))->co;
v3= (def_mesh->mvert+(mface->v3))->co;
v4= (def_mesh->mvert+(mface->v4))->co;
-
+
VECCOPY(nv1, v1);
VECCOPY(nv2, v2);
VECCOPY(nv3, v3);
VECCOPY(nv4, v4);
-
+
/*Apply the objects deformation matrix*/
Mat3MulVecfl(mat, nv1);
Mat3MulVecfl(mat, nv2);
Mat3MulVecfl(mat, nv3);
Mat3MulVecfl(mat, nv4);
-
+
VECADD(nv1, nv1, obloc);
VECADD(nv2, nv2, obloc);
VECADD(nv3, nv3, obloc);
@@ -1633,39 +1632,31 @@ int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
}
deflected_now = 0;
-
+
if (mode == 1){ // face intrusion test
// switch origin to be nv2
VECSUB(edge1, nv1, nv2);
VECSUB(edge2, nv3, nv2);
VECSUB(dv1,opco,nv2); // abuse dv1 to have vertex in question at *origin* of triangle
- len_u=Normalise(edge1);
- len_v=Normalise(edge2);
+ Crossf(d_nvect, edge2, edge1);
+ n_mag = Normalise(d_nvect);
+ facedist = Inpf(dv1,d_nvect);
- u = Inpf(dv1,edge1)/len_u;
- v = Inpf(dv1,edge2)/len_v;
- if ( (u >= 0.0f) && (v >= 0.0f) && ((u+v) <= 1.0)){ // inside prims defined by triangle and normal
- Crossf(d_nvect, edge2, edge1);
- n_mag = Normalise(d_nvect);
- // ok lets add force
- facedist = Inpf(dv1,d_nvect);
- if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){
- //force_mag_norm =ee*(facedist - outerfacethickness)*(facedist - outerfacethickness);
+ 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 ( linetriangle( opco, dv2, nv1, nv2, nv3, &t)){
force_mag_norm =(float)exp(-ee*facedist);
if (facedist > outerfacethickness*ff)
- force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
-
+ force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
+
force[0] += force_mag_norm*d_nvect[0] ;
force[1] += force_mag_norm*d_nvect[1] ;
force[2] += force_mag_norm*d_nvect[2] ;
*damp=ob->pd->pdef_sbdamp;
deflected = 2;
-
- colco[0] = nv2[0] + len_u*u*edge1[0] + len_v*v*edge2[0];
- colco[1] = nv2[1] + len_u*u*edge1[1] + len_v*v*edge2[1];
- colco[2] = nv2[2] + len_u*u*edge1[2] + len_v*v*edge2[2];
-
}
}
if (mface->v4){ // quad
@@ -1674,31 +1665,24 @@ int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
VECSUB(edge2, nv1, nv4);
VECSUB(dv1,opco,nv4); // abuse dv1 to have vertex in question at *origin* of triangle
- len_u=Normalise(edge1);
- len_v=Normalise(edge2);
+ Crossf(d_nvect, edge2, edge1);
+ n_mag = Normalise(d_nvect);
+ facedist = Inpf(dv1,d_nvect);
- u = Inpf(dv1,edge1)/len_u;
- v = Inpf(dv1,edge2)/len_v;
- if ( (u >= 0.0f) && (v >= 0.0f) && ((u+v) <= 1.0)){ // inside prims defined by triangle and normal
- Crossf(d_nvect, edge2, edge1);
- n_mag = Normalise(d_nvect);
- // ok lets add force
- facedist = Inpf(dv1,d_nvect);
- if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){
- //force_mag_norm =ee*(facedist - outerfacethickness)*(facedist - outerfacethickness);
- force_mag_norm =(float)exp(-ee*facedist);
- if (facedist > outerfacethickness*ff)
- force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
-
+ 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 ( linetriangle( opco, dv2, nv1, nv3, nv4, &t)){
+ force_mag_norm =(float)exp(-ee*facedist);
+ if (facedist > outerfacethickness*ff)
+ force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
+
force[0] += force_mag_norm*d_nvect[0] ;
force[1] += force_mag_norm*d_nvect[1] ;
force[2] += force_mag_norm*d_nvect[2] ;
*damp=ob->pd->pdef_sbdamp;
deflected = 2;
- colco[0] = nv4[0] + len_u*u*edge1[0] + len_v*v*edge2[0];
- colco[1] = nv4[1] + len_u*u*edge1[1] + len_v*v*edge2[1];
- colco[2] = nv4[2] + len_u*u*edge1[2] + len_v*v*edge2[2];
-
}
}
@@ -1707,58 +1691,58 @@ int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
if (mode == 2){ // edge intrusion test
-// t= 0.5; // this is labda of line, can use it optimize quad intersection
-// sorry but no .. see below (BM)
- if( linetriangle(opco, npco, nv1, nv2, nv3, &t) ) {
- if (t < min_t) {
- deflected = 1;
- deflected_now = 1;
- }
- }
-// else if (mface->v4 && (t>=0.0 && t<=1.0)) {
-// no, you can't skip testing the other triangle
-// it might give a smaller t on (close to) the edge .. this is numerics not esoteric maths :)
-// note: the 2 triangles don't need to share a plane ! (BM)
- if (mface->v4) {
- if( linetriangle(opco, npco, nv1, nv3, nv4, &t2) ) {
- if (t2 < min_t) {
+ //t= 0.5; // this is labda of line, can use it optimize quad intersection
+ // sorry but no .. see below (BM)
+ if( linetriangle(opco, npco, nv1, nv2, nv3, &t) ) {
+ if (t < min_t) {
deflected = 1;
- deflected_now = 2;
+ deflected_now = 1;
}
- }
- }
-
- if ((deflected_now > 0) && ((t < min_t) ||(t2 < min_t))) {
- min_t = t;
- ds_object = d_object;
- ds_face = d_face;
- deflection_object = ob;
- deflection_face = mface;
- if (deflected_now==1) {
- min_t = t;
- VECCOPY(dv1, nv1);
- VECCOPY(dv2, nv2);
- VECCOPY(dv3, nv3);
}
- else {
- min_t = t2;
- VECCOPY(dv1, nv1);
- VECCOPY(dv2, nv3);
- VECCOPY(dv3, nv4);
+ // else if (mface->v4 && (t>=0.0 && t<=1.0)) {
+ // no, you can't skip testing the other triangle
+ // it might give a smaller t on (close to) the edge .. this is numerics not esoteric maths :)
+ // note: the 2 triangles don't need to share a plane ! (BM)
+ if (mface->v4) {
+ if( linetriangle(opco, npco, nv1, nv3, nv4, &t2) ) {
+ if (t2 < min_t) {
+ deflected = 1;
+ deflected_now = 2;
+ }
+ }
}
- }
- } // not -100
+
+ if ((deflected_now > 0) && ((t < min_t) ||(t2 < min_t))) {
+ min_t = t;
+ ds_object = d_object;
+ ds_face = d_face;
+ deflection_object = ob;
+ deflection_face = mface;
+ if (deflected_now==1) {
+ min_t = t;
+ VECCOPY(dv1, nv1);
+ VECCOPY(dv2, nv2);
+ VECCOPY(dv3, nv3);
+ }
+ else {
+ min_t = t2;
+ VECCOPY(dv1, nv1);
+ VECCOPY(dv2, nv3);
+ VECCOPY(dv3, nv4);
+ }
+ }
+ }
mface++;
}
}
}
base = base->next;
} // while (base)
-
+
if (mode == 1){ // face
return deflected;
- }
-
+ }
+
if (mode == 2){ // edge intrusion test
if (deflected) {
VECSUB(edge1, dv1, dv2);
@@ -1770,14 +1754,7 @@ int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
colco[1] = opco[1] + (min_t * (npco[1] - opco[1]));
colco[2] = opco[2] + (min_t * (npco[2] - opco[2]));
- VECCOPY(facenormal,d_nvect);
- {
- facenormal[0] *= -1.0f;
- facenormal[1] *= -1.0f;
- facenormal[2] *= -1.0f;
- }
-
-
+ VECCOPY(facenormal,d_nvect);
}
}
return deflected;