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
This commit is contained in:
parent
99ee891596
commit
1d47d662f9
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,7 +299,29 @@ 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 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 (bounce) *bounce *= 1.5f;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@ -312,160 +335,14 @@ static int sb_deflect_particle(Object *ob,float *actpos, float *futurepos,float
|
||||
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, dummy, dummy , 2,
|
||||
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)
|
||||
{
|
||||
|
||||
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;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user