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-04-19 01:51:45 +0400
committerJens Ole Wund <bjornmose@gmx.net>2005-04-19 01:51:45 +0400
commit1d47d662f9c6b5a2bcaec90b1a4ff78781107553 (patch)
tree47f95a887d81844a172cd7470b188a82c90b0e91 /source/blender/blenkernel
parent99ee8915969ad4cdb55c88c025e674f4c1cb89fd (diff)
removed my SB hack from particle collision code
(which still can't really handle moving targets) leaving 2 bug fixes 1. multiple objects need a reset on cache variable 2. quads always need to be handled as 2 triangles (since they don't need to share a plane) added a collision detecting function in effect.c for SB ( no need to be there, but i did not find a better place ) but should handle 'moving targets' up to 0.2 blender units/frame well .. important info in this case: collision uses 'face normal' to decide if *intrusion* happend uses 'damping' of collision target to slow down movement when *intrusion* happend +some more removing unneeded code in softbody.c
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_effect.h5
-rw-r--r--source/blender/blenkernel/BKE_softbody.h1
-rw-r--r--source/blender/blenkernel/intern/effect.c294
-rw-r--r--source/blender/blenkernel/intern/softbody.c415
4 files changed, 368 insertions, 347 deletions
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index e7eca88535c..4d5ab274fc5 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -70,6 +70,11 @@ int pdDoDeflection(float opco[3], float npco[3], float opno[3],
float cur_time, unsigned int par_layer, int *last_object,
int *last_face, int *same_face);
+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, int *last_object,
+ int *last_face, int *same_face);
+
#endif
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index 09be644c9e7..e612769c305 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -39,6 +39,7 @@ typedef struct BodyPoint {
float weight, goal;
float prevpos[3], prevvec[3], prevdx[3], prevdv[3]; /* used for Heun integration */
int nofsprings; int *springs;
+ float contactfrict;
} BodyPoint;
typedef struct BodySpring {
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 5f77d40530c..46b6e330754 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -607,6 +607,8 @@ int pdDoDeflection(float opco[3], float npco[3], float opno[3],
obloc[0] = ob->obmat[3][0];
obloc[1] = ob->obmat[3][1];
obloc[2] = ob->obmat[3][2];
+ vcache= NULL;
+
}
while (a--) {
@@ -646,7 +648,9 @@ int pdDoDeflection(float opco[3], float npco[3], float opno[3],
}
deflected_now = 0;
-
+
+
+
// 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) ) {
@@ -694,34 +698,6 @@ int pdDoDeflection(float opco[3], float npco[3], float opno[3],
base = base->next;
}
- if (def_depth == -1){ // evil hack to signal softbodies
- if (deflected) {
- VECSUB(edge1, dv1, dv2);
- VECSUB(edge2, dv3, dv2);
- Crossf(d_nvect, edge2, edge1);
- n_mag = Normalise(d_nvect);
- dk_plane = INPR(d_nvect, nv1);
- dk_point1 = INPR(d_nvect,opco);
-
- VECSUB(d_intersect_vect, npco, opco);
- // abuse opno to return point of intersection
- opno[0] = opco[0] + (min_t * (npco[0] - opco[0]));
- opno[1] = opco[1] + (min_t * (npco[1] - opco[1]));
- opno[2] = opco[2] + (min_t * (npco[2] - opco[2]));
-
- // abuse npno to return face normal
- VECCOPY(npno,d_nvect);
- {
- npno[0] *= -1.0f;
- npno[1] *= -1.0f;
- npno[2] *= -1.0f;
- }
-
-
- }
- return(deflected);
-
- }
/* Here's the point to do the permeability calculation */
/* Set deflected to 0 if a random number is below the value */
@@ -1540,3 +1516,263 @@ int object_wave(Object *ob)
}
return 1;
}
+
+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, int *last_object,
+ int *last_face, int *same_face)
+{
+ Base *base;
+ Object *ob, *deflection_object = NULL;
+ Mesh *def_mesh;
+ MFace *mface, *deflection_face = NULL;
+ float *v1, *v2, *v3, *v4, *vcache=NULL;
+ float mat[3][3];
+ float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], obloc[3];
+ float dv1[3], dv2[3], dv3[3];
+ float facedist,n_mag,t,t2, min_t,force_mag_norm;
+ 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 declatation rules when WIP is finoshed (BM)
+ float u,v,len_u,len_v;
+ float innerfacethickness = -0.5f;
+ float outerfacethickness = 0.2f;
+ float ee = 5.0f;
+ float ff = 0.1f;
+ float fa;
+
+ fa = (ff*outerfacethickness-outerfacethickness);
+ fa *= fa;
+ fa = 1.0f/fa;
+
+ min_t = 200000;
+
+ /* The first part of the code, finding the first intersected face*/
+ 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;
+ /* 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;
+
+
+ if(ob->parent==NULL && ob->ipo==NULL) { // static
+ if(ob->sumohandle==NULL) cache_object_vertices(ob);
+ vcache= ob->sumohandle;
+ }
+ else {
+ /*Find out where the object is at this time*/
+ cur_frame = G.scene->r.cfra;
+ G.scene->r.cfra = (short)cur_time;
+ where_is_object_time(ob, cur_time);
+ G.scene->r.cfra = cur_frame;
+
+ /*Pass the values from ob->obmat to mat*/
+ /*and the location values to obloc */
+ Mat3CpyMat4(mat,ob->obmat);
+ obloc[0] = ob->obmat[3][0];
+ obloc[1] = ob->obmat[3][1];
+ obloc[2] = ob->obmat[3][2];
+ /* not cachable */
+ vcache= NULL;
+
+ }
+
+ while (a--) {
+
+ if(vcache) {
+ v1= vcache+ 3*(mface->v1);
+ VECCOPY(nv1, v1);
+ v1= vcache+ 3*(mface->v2);
+ VECCOPY(nv2, v1);
+ v1= vcache+ 3*(mface->v3);
+ VECCOPY(nv3, v1);
+ v1= vcache+ 3*(mface->v4);
+ VECCOPY(nv4, v1);
+ }
+ else {
+ /* Calculate the global co-ordinates of the vertices*/
+ v1= (def_mesh->mvert+(mface->v1))->co;
+ 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);
+ VECADD(nv4, nv4, obloc);
+ }
+
+ 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);
+
+ 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 =exp(-ee*facedist);
+ if (facedist > outerfacethickness*ff)
+ force_mag_norm =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_damp;
+ 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
+ // switch origin to be nv4
+ VECSUB(edge1, nv3, nv4);
+ 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);
+
+ 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 =exp(-ee*facedist);
+ if (facedist > outerfacethickness*ff)
+ force_mag_norm =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_damp;
+ 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];
+
+ }
+ }
+
+ }
+ }
+ 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) {
+ deflected = 1;
+ deflected_now = 2;
+ }
+ }
+ }
+
+ 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);
+ }
+ }
+ } // not -100
+ mface++;
+ }
+ }
+ }
+ base = base->next;
+ } // while (base)
+
+ if (mode == 1){ // face
+ last_object = deflection_object;
+ return deflected;
+ }
+
+ if (mode == 2){ // edge intrusion test
+ if (deflected) {
+ VECSUB(edge1, dv1, dv2);
+ VECSUB(edge2, dv3, dv2);
+ Crossf(d_nvect, edge2, edge1);
+ n_mag = Normalise(d_nvect);
+ // return point of intersection
+ colco[0] = opco[0] + (min_t * (npco[0] - opco[0]));
+ 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;
+ }
+
+
+ }
+ }
+ return deflected;
+}
+
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index e6d6dd7c341..ab5e50d9440 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -87,6 +87,7 @@ extern int get_defgroup_num (Object *ob, bDeformGroup *dg);
// removes *unnecessary* stiffnes from ODE system
#define HEUNWARNLIMIT 1 // 50 would be fine i think for detecting severe *stiff* stuff
+
float SoftHeunTol = 1.0f; // humm .. this should be calculated from sb parameters and sizes
/* local prototypes */
@@ -298,174 +299,50 @@ static void Vec3PlusStVec(float *v, float s, float *v1)
v[2] += s*v1[2];
}
-static int sb_deflect_particle(Object *ob,float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *slip ,float *bounce)
+static int sb_deflect_face(Object *ob,float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *force,float *cf ,float *bounce)
{
int deflected;
int last_ob = -1;
int last_fc = -1;
int same_fc = 0;
- float dummy[3],s_actpos[3], s_futurepos[3];
+ float s_actpos[3], s_futurepos[3];
SoftBody *sb= ob->soft; // is supposed to be there
VECCOPY(s_actpos,actpos);
+ if(futurepos)
VECCOPY(s_futurepos,futurepos);
- if (slip) *slip *= 0.98f;
if (bounce) *bounce *= 1.5f;
- deflected= pdDoDeflection(s_actpos, s_futurepos, collisionpos,
- facenormal, sb->ctime, dummy , -1,
+ deflected= SoftBodyDetectCollision(s_actpos, s_futurepos, collisionpos,
+ facenormal, cf, force , 1,
G.scene->r.cfra, ob->lay, &last_ob, &last_fc, &same_fc);
return(deflected);
}
-#if 0
-static int sb_deflect_test(float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *slip ,float *bounce)
+/* for future use (BM)
+static int sb_deflect_edge_face(Object *ob,float *actpos, float *futurepos,float *collisionpos, float *facenormal,float *slip ,float *bounce)
{
-
+ int deflected;
+ int last_ob = -1;
+ int last_fc = -1;
+ int same_fc = 0;
+ float dummy[3],s_actpos[3], s_futurepos[3];
+ SoftBody *sb= ob->soft; // is supposed to be there
+ VECCOPY(s_actpos,actpos);
+ VECCOPY(s_futurepos,futurepos);
if (slip) *slip *= 0.98f;
if (bounce) *bounce *= 1.5f;
-
- if (
- ( futurepos[0] > 0.0) && ( futurepos[0] < 1.0) // having unit square acting as defelecting region
- && ( futurepos[1] > 0.0) && ( futurepos[1] < 1.0)
- && ( (( futurepos[2] > 1.0) && ( actpos[2] <= 1.0)) //intersecting at z == 1;
- ||(( futurepos[2] < 1.0) && ( actpos[2] >= 1.0))) )
-
- {
- if (facenormal){
- facenormal[0] = 0.0f;
- facenormal[1] = 0.0f;
- facenormal[2] = -1.0f;
- }
- if (collisionpos){
- collisionpos[0] = (actpos[0] + futurepos[0])/2.0f;
- collisionpos[1] = (actpos[1] + futurepos[1])/2.0f;
- collisionpos[2] = 1.0f;
- }
- return 1;
-
- }
-
- if (
- ( futurepos[0] > 0.0) && ( futurepos[0] < 1.0) // having unit square acting as defelecting region
- && ( futurepos[1] > 0.0) && ( futurepos[1] < 1.0)
- && ( (( futurepos[2] > 0.0) && ( actpos[2] <= 0.0)) //intersecting at z == 1;
- ||(( futurepos[2] < 0.0) && ( actpos[2] >= 0.0)) ) )
-
- {
- if (facenormal){
- facenormal[0] = 0.0f;
- facenormal[1] = 0.0f;
- if (futurepos[2] < 0.0)
- facenormal[2] = -1.0f;
- else facenormal[2] = 1.0f;
- }
- if (collisionpos){
- collisionpos[0] = (actpos[0] + futurepos[0])/2.0f;
- collisionpos[1] = (actpos[1] + futurepos[1])/2.0f;
- collisionpos[2] = 0.0f;
- }
- return 1;
-
- }
-
- if (
- ( futurepos[2] > 0.0) && ( futurepos[2] < 1.0) // having unit square acting as defelecting region
- && ( futurepos[1] > 0.0) && ( futurepos[1] < 1.0)
- && (
- /* (( futurepos[0] > 1.0) && ( actpos[0] <= 1.0)) //intersecting at x == 1;
- ||*/
-
- /* experiment distinguish inside and outside*/
-
- (( futurepos[0] < 1.0) && ( actpos[0] >= 1.0))) )
-
- {
- if (facenormal){
- facenormal[0] = -1.0f;
- facenormal[1] = 0.0f;
- facenormal[2] = 0.0f;
- }
- if (collisionpos){
- collisionpos[0] = 1.0f;
- collisionpos[1] = (actpos[1] + futurepos[1])/2.0f;
- collisionpos[2] = (actpos[2] + futurepos[2])/2.0f;
- }
- return 1;
-
- }
-
- if (
- ( futurepos[2] > 0.0) && ( futurepos[2] < 1.0) // having unit square acting as defelecting region
- && ( futurepos[1] > 0.0) && ( futurepos[1] < 1.0)
- && ( (( futurepos[0] > 0.0) && ( actpos[0] <= 0.0)) //intersecting at x == 0;
- ||(( futurepos[0] < 0.0) && ( actpos[0] >= 0.0))) )
-
- {
- if (facenormal){
- facenormal[0] = 1.0f;
- facenormal[1] = 0.0f;
- facenormal[2] = 0.0f;
- }
- if (collisionpos){
- collisionpos[0] = 0.0f;
- collisionpos[1] = (actpos[1] + futurepos[1])/2.0f;
- collisionpos[2] = (actpos[2] + futurepos[2])/2.0f;
- }
- return 1;
-
- }
-
-
- if (
- ( futurepos[0] > 0.0) && ( futurepos[0] < 1.0) // having unit square acting as defelecting region
- && ( futurepos[2] > 0.0) && ( futurepos[2] < 1.0)
- && ( (( futurepos[1] > 0.0) && ( actpos[1] <= 0.0)) //intersecting at Y == 0;
- ||(( futurepos[1] < 0.0) && ( actpos[1] >= 0.0))) )
-
- {
- if (facenormal){
- facenormal[0] = 0.0f;
- facenormal[1] = 1.0f;
- facenormal[2] = 0.0f;
- }
- if (collisionpos){
- collisionpos[0] = (actpos[0] + futurepos[0])/2.0f;
- collisionpos[2] = (actpos[2] + futurepos[2])/2.0f;
- collisionpos[1] = 0.0f;
- }
- return 1;
-
- }
- if (
- ( futurepos[0] > 0.0) && ( futurepos[0] < 1.0) // having unit square acting as defelecting region
- && ( futurepos[2] > 0.0) && ( futurepos[2] < 1.0)
- && ( (( futurepos[1] > 1.0) && ( actpos[1] <= 1.0)) //intersecting at Y == 0;
- ||(( futurepos[1] < 1.0) && ( actpos[1] >= 1.0))) )
-
- {
- if (facenormal){
- facenormal[0] = 0.0f;
- facenormal[1] = -1.0f;
- facenormal[2] = 0.0f;
- }
- if (collisionpos){
- collisionpos[0] = (actpos[0] + futurepos[0])/2.0f;
- collisionpos[2] = (actpos[2] + futurepos[2])/2.0f;
- collisionpos[1] = 1.0f;
- }
- return 1;
-
- }
-
-
-
-return 0;
+
+
+ deflected= SoftBodyDetectCollision(s_actpos, s_futurepos, collisionpos,
+ facenormal, dummy, dummy , 2,
+ G.scene->r.cfra, ob->lay, &last_ob, &last_fc, &same_fc);
+ return(deflected);
+
}
-#endif
-
-
+*/
+// some functions removed here .. to help HOS on next merge (BM)
#define USES_FIELD 1
#define USES_DEFLECT 2
@@ -521,7 +398,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
/* calulate damping forces generated by goals*/
VecSubf(velgoal,bp->origS, bp->origE);
kd = sb->goalfrict * sb_fric_force_scale(ob) ;
-
+
if (forcetime > 0.0 ) { // make sure friction does not become rocket motor on time reversal
bp->force[0]-= kd * (velgoal[0] + bp->vec[0]);
bp->force[1]-= kd * (velgoal[1] + bp->vec[1]);
@@ -538,7 +415,7 @@ static void softbody_calc_forces(Object *ob, float forcetime)
/* gravitation */
bp->force[2]-= gravity*sb->nodemass; /* individual mass of node here */
-
+
/* particle field & vortex */
if(do_effector & USES_FIELD) {
float force[3]= {0.0f, 0.0f, 0.0f};
@@ -554,17 +431,17 @@ static void softbody_calc_forces(Object *ob, float forcetime)
VECADD(bp->force, bp->force, force);
/* apply speed. note; deflector can give 'speed' only.... */
/* nooo! we never alter free variables :bp->vec bp->pos in here !
- * this will ruin adative stepsize AHA heun! (BM)
- * VECADD(bp->vec, bp->vec, speed);
- */
- /* friction in moving media */
-
- kd= sb->mediafrict* eval_sb_fric_force_scale;
+ * this will ruin adative stepsize AHA heun! (BM)
+ * VECADD(bp->vec, bp->vec, speed);
+ */
+ /* friction in moving media */
+
+ kd= sb->mediafrict* eval_sb_fric_force_scale;
bp->force[0] -= kd * (bp->vec[0] + speed[0]/eval_sb_fric_force_scale);
bp->force[1] -= kd * (bp->vec[1] + speed[1]/eval_sb_fric_force_scale);
bp->force[2] -= kd * (bp->vec[2] + speed[2]/eval_sb_fric_force_scale);
/* now we'll have nice centrifugal effect for vortex */
-
+
}
else {
/* friction in media (not) moving*/
@@ -575,42 +452,38 @@ static void softbody_calc_forces(Object *ob, float forcetime)
bp->force[2]-= bp->vec[2]*kd;
/* friction in media done */
}
-
+
/*other forces*/
/* this is the place where other forces can be added
yes, constraints and collision stuff should go here too (read baraff papers on that!)
*/
-#if 0
- /* copied from particles... doesn't work really! */
+ /* try to match moving collision targets */
+ /* master switch to turn collision off (BM)*/
+ //if(0) {
if(do_effector & USES_DEFLECT) {
- int deflected;
- int last_ob = -1;
- int last_fc = -1;
- int same_fc = 0;
- float last[3], lastv[3];
- int finish_defs = 1;
- int def_count = 0;
+ /*sorry for decl. here i'll move 'em up when WIP is done (BM) */
+ float defforce[3];
+ float collisionpos[3],facenormal[3];
+ float cf = 1.0f;
+ float bounce = 0.5f;
+ kd = 1.0f;
+ defforce[0] = 0.0f;
+ defforce[1] = 0.0f;
+ defforce[2] = 0.0f;
- VecSubf(last, bp->pos, bp->vec);
- VECCOPY(lastv, bp->vec);
-
- while (finish_defs) {
- deflected= pdDoDeflection(last, bp->pos, lastv,
- bp->vec, dtime, bp->force, 0,
- G.scene->r.cfra, ob->lay, &last_ob, &last_fc, &same_fc);
- if (deflected) {
- def_count = def_count + 1;
- //deflection = 1;
- if (def_count==10) finish_defs = 0;
- }
- else {
- finish_defs = 0;
- }
+ if (sb_deflect_face(ob,bp->pos, bp->pos, collisionpos, facenormal,defforce,&cf,&bounce)){
+ bp->force[0] += defforce[0]*kd;
+ bp->force[1] += defforce[1]*kd;
+ bp->force[2] += defforce[2]*kd;
+ bp->contactfrict = cf;
+ }
+ else{
+ bp->contactfrict = 0.0f;
}
+
}
-#endif
+
/*other forces done*/
-
/* nice things could be done with anisotropic friction
like wind/air resistance in normal direction
--> having a piece of cloth sailing down
@@ -618,72 +491,31 @@ static void softbody_calc_forces(Object *ob, float forcetime)
*valid* means to be calulated on time axis
hrms .. may be a rough one could be used as well .. let's see
*/
-
+
if(ob->softflag & OB_SB_EDGES) {
- if (1){ /* big mesh optimization */
- /* run over attached inner spring list */
- if (sb->bspring){ // spring list exists at all ?
- for(b=bp->nofsprings;b>0;b--){
- bs = sb->bspring + bp->springs[b-1];
- if (( (sb->totpoint-a) == bs->v1) ){
- actspringlen= VecLenf( (bproot+bs->v2)->pos, bp->pos);
- VecSubf(sd,(bproot+bs->v2)->pos, bp->pos);
- Normalise(sd);
-
- // friction stuff V1
- VecSubf(velgoal,bp->vec,(bproot+bs->v2)->vec);
- kd = sb->infrict * sb_fric_force_scale(ob);
- absvel = Normalise(velgoal);
- projvel = ABS(Inpf(sd,velgoal));
- kd *= absvel * projvel;
- Vec3PlusStVec(bp->force,-kd,velgoal);
-
- if(bs->len > 0.0) /* check for degenerated springs */
- forcefactor = (bs->len - actspringlen)/bs->len * iks;
- else
- forcefactor = actspringlen * iks;
-
- Vec3PlusStVec(bp->force,-forcefactor,sd);
-
- }
-
- if (( (sb->totpoint-a) == bs->v2) ){
- actspringlen= VecLenf( (bproot+bs->v1)->pos, bp->pos);
- VecSubf(sd,bp->pos,(bproot+bs->v1)->pos);
- Normalise(sd);
-
- // friction stuff V2
- VecSubf(velgoal,bp->vec,(bproot+bs->v1)->vec);
- kd = sb->infrict * sb_fric_force_scale(ob);
- absvel = Normalise(velgoal);
- projvel = ABS(Inpf(sd,velgoal));
- kd *= absvel * projvel;
- Vec3PlusStVec(bp->force,-kd,velgoal);
-
- if(bs->len > 0.0)
- forcefactor = (bs->len - actspringlen)/bs->len * iks;
- else
- forcefactor = actspringlen * iks;
- Vec3PlusStVec(bp->force,+forcefactor,sd);
- }
- }
- } //if spring list exists at all ?
- }
- else{ // this branch is not completly uptaded for friction stuff
- /* scan for attached inner springs makes it a O(N^2) thing = bad !*/
- /* obsolete .. but if someone wants to try the effect :) */
- for(b=sb->totspring, bs= sb->bspring; b>0; b--, bs++) {
+ if (sb->bspring){ // spring list exists at all ?
+ for(b=bp->nofsprings;b>0;b--){
+ bs = sb->bspring + bp->springs[b-1];
if (( (sb->totpoint-a) == bs->v1) ){
actspringlen= VecLenf( (bproot+bs->v2)->pos, bp->pos);
VecSubf(sd,(bproot+bs->v2)->pos, bp->pos);
Normalise(sd);
-
-
+
+ // friction stuff V1
+ VecSubf(velgoal,bp->vec,(bproot+bs->v2)->vec);
+ kd = sb->infrict * sb_fric_force_scale(ob);
+ absvel = Normalise(velgoal);
+ projvel = ABS(Inpf(sd,velgoal));
+ kd *= absvel * projvel;
+ Vec3PlusStVec(bp->force,-kd,velgoal);
+
if(bs->len > 0.0) /* check for degenerated springs */
forcefactor = (bs->len - actspringlen)/bs->len * iks;
else
forcefactor = actspringlen * iks;
+
Vec3PlusStVec(bp->force,-forcefactor,sd);
+
}
if (( (sb->totpoint-a) == bs->v2) ){
@@ -691,17 +523,25 @@ static void softbody_calc_forces(Object *ob, float forcetime)
VecSubf(sd,bp->pos,(bproot+bs->v1)->pos);
Normalise(sd);
+ // friction stuff V2
+ VecSubf(velgoal,bp->vec,(bproot+bs->v1)->vec);
+ kd = sb->infrict * sb_fric_force_scale(ob);
+ absvel = Normalise(velgoal);
+ projvel = ABS(Inpf(sd,velgoal));
+ kd *= absvel * projvel;
+ Vec3PlusStVec(bp->force,-kd,velgoal);
+
if(bs->len > 0.0)
forcefactor = (bs->len - actspringlen)/bs->len * iks;
else
forcefactor = actspringlen * iks;
- Vec3PlusStVec(bp->force,+forcefactor,sd);
+ Vec3PlusStVec(bp->force,+forcefactor,sd);
}
- }// no snap
- }//for
- }// if use edges
- }
- }
+ }/* loop springs */
+ }/* existing spring list */
+ }/*any edges*/
+ }/*omit on snap */
+ }/*loop all bp's*/
}
static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *err)
@@ -714,9 +554,11 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
float dx[3],dv[3];
float timeovermass;
float maxerr = 0.0;
- int a;
+ int a, do_effector;
forcetime *= sb_time_scale(ob);
+ /* check! */
+ do_effector= is_there_deflection(ob->lay);
// claim a minimum mass for vertex
if (sb->nodemass > 0.09999f) timeovermass = forcetime/sb->nodemass;
@@ -772,79 +614,15 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
maxerr = MAX2(maxerr,ABS(dx[0] - bp->prevdx[0]));
maxerr = MAX2(maxerr,ABS(dx[1] - bp->prevdx[1]));
maxerr = MAX2(maxerr,ABS(dx[2] - bp->prevdx[2]));
- }
- else { VECADD(bp->pos, bp->pos, dx);}
- if(1) {
-
- // experimental collision
- // we need the above calcualtions done though we'll over ride bp->pos bp->vel
- if (mode ==2){
- float vv[3],collisionpos[3],facenormal[3];
- float slip = 1.0f;
- float bounce = 1.0f;
- float projvel;
- float deswampingconstant = 0.0001;
-
-
-
- /*
- slip = sb->slip; // parameter for tangetial interaction
- bounce = sb->bounce; // parameter for normal interaction
- */
- // if (sb_deflect_test(bp->prevpos, bp->pos, collisionpos, facenormal,&slip,&bounce)){
- if (sb_deflect_particle(ob,bp->prevpos, bp->pos, collisionpos, facenormal,&slip,&bounce)){
-
-
- VecSubf(vv,bp->pos,bp->prevpos);
- projvel = ABS(Inpf(vv,facenormal));
-
-
- if (1) // mushy impact
- {
- float tangential_vel[3];
- float helper_vect[3];
- float hf;
- hf = Inpf(bp->vec,facenormal);
- /* make helper_vect vel along normal */
- helper_vect[0] = hf * facenormal[0];
- helper_vect[1] = hf * facenormal[1];
- helper_vect[2] = hf * facenormal[2];
- /* now we have a nice slip along vector */
- VecSubf(tangential_vel,bp->vec,helper_vect);
-
- bp->vec[0] = tangential_vel[0]* slip - (bounce * 2.0f * projvel * facenormal[0]);
- bp->vec[1] = tangential_vel[1]* slip - (bounce * 2.0f * projvel * facenormal[1]);
- bp->vec[2] = tangential_vel[2]* slip - (bounce * 2.0f * projvel * facenormal[2]);
- }
- else{
- // 100 % sticky surface
- bp->vec[0] = vv[0] - (bounce * 2.0f * projvel * facenormal[0]);
- bp->vec[1] = vv[1] - (bounce * 2.0f * projvel * facenormal[1]);
- bp->vec[2] = vv[2] - (bounce * 2.0f * projvel * facenormal[2]);
- }
- // pull our vertex out of the swamp .. not very accurate but who will notice
- /*
- bp->pos[0] = collisionpos[0] + deswampingconstant * bp->vec[0] ;
- bp->pos[1] = collisionpos[1] + deswampingconstant * bp->vec[1] ;
- bp->pos[2] = collisionpos[2] + deswampingconstant * bp->vec[2];
- */
- bp->pos[0] = collisionpos[0] - deswampingconstant * facenormal[0] ;
- bp->pos[1] = collisionpos[1] - deswampingconstant * facenormal[1] ;
- bp->pos[2] = collisionpos[2] - deswampingconstant * facenormal[2];
- maxerr = MAX2(maxerr,ABS(bounce*vv[0]));
- maxerr = MAX2(maxerr,ABS(bounce*vv[1]));
- maxerr = MAX2(maxerr,ABS(bounce*vv[2]));
-
- /* */
-
-
+/* kind of hack .. while inside collision target .. make movement more *viscous* */
+ if (bp->contactfrict > 0.0f){
+ bp->vec[0] *= (1.0 - bp->contactfrict);
+ bp->vec[1] *= (1.0 - bp->contactfrict);
+ bp->vec[2] *= (1.0 - bp->contactfrict);
}
}
- }
-
-
-
-
+ else { VECADD(bp->pos, bp->pos, dx);}
+// experimental particle collision suff was here .. just to help HOS on next merge (BM)
}//snap
} //for
if (err){ /* so step size will be controlled by biggest difference in slope */
@@ -970,6 +748,7 @@ static void set_body_point(Object *ob, BodyPoint *bp, float *vec)
bp->nofsprings= 0;
bp->springs= NULL;
+ bp->contactfrict = 0.0f;
}