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-08-20 02:55:05 +0400
committerJens Ole Wund <bjornmose@gmx.net>2005-08-20 02:55:05 +0400
commitd81a5abf3252aff1f09c40bd5046700ddfe6676e (patch)
tree34a0b27dd4b275870954d346ccd2ae4a67282883 /source/blender/blenkernel
parent6d60b0acfe9dd30239cb3223bec525d456efb3b2 (diff)
Moving functions and calls to have a cleaner situation for futre work (implicit solver .. n stuff)
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_effect.h3
-rw-r--r--source/blender/blenkernel/intern/effect.c286
-rw-r--r--source/blender/blenkernel/intern/softbody.c255
3 files changed, 256 insertions, 288 deletions
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index f371220bab5..cb58496465f 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -59,9 +59,6 @@ void build_particle_system(struct Object *ob);
void pdDoEffector(float *opco, float *force, float *speed, float cur_time, unsigned int par_layer,unsigned int flags);
-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);
#endif
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 1c2365902f5..75bb86d2f22 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -300,36 +300,6 @@ static void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no)
}
}
-
-static int linetriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *labda)
-{
- float p[3], s[3], d[3], e1[3], e2[3], q[3];
- float a, f, u, v;
-
- VECSUB(e1, v1, v0);
- VECSUB(e2, v2, v0);
- VECSUB(d, p2, p1);
-
- Crossf(p, d, e2);
- a = INPR(e1, p);
- if ((a > -0.000001) && (a < 0.000001)) return 0;
- f = 1.0f/a;
-
- VECSUB(s, p1, v0);
-
- Crossf(q, s, e1);
- *labda = f * INPR(e2, q);
- if ((*labda < 0.0)||(*labda > 1.0)) return 0;
-
- u = f * INPR(s, p);
- if ((u < 0.0)||(u > 1.0)) return 0;
-
- v = f * INPR(d, q);
- if ((v < 0.0)||((u + v) > 1.0)) return 0;
-
- return 1;
-}
-
/* -------- pdDoEffector() --------
generic force/speed system, now used for particles and softbodies
opco = global coord, as input
@@ -603,7 +573,7 @@ static int pdDoDeflection(RNG *rng, float opco[3], float npco[3], float opno[3],
// 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( LineIntersectsTriangle(opco, npco, nv1, nv2, nv3, &t) ) {
if (t < min_t) {
deflected = 1;
deflected_now = 1;
@@ -614,7 +584,7 @@ static int pdDoDeflection(RNG *rng, float opco[3], float npco[3], float opno[3],
// 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( LineIntersectsTriangle(opco, npco, nv1, nv3, nv4, &t2) ) {
if (t2 < min_t) {
deflected = 1;
deflected_now = 2;
@@ -1383,255 +1353,3 @@ void build_particle_system(Object *ob)
rng_free(rng);
}
-
-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)
-{
-// static short recursion = 0;
-// static short didokee = 0;
- Base *base;
- Object *ob;
- float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[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;
- 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 innerfacethickness = -0.5f;
- float outerfacethickness = 0.2f;
- float ee = 5.0f;
- float ff = 0.1f;
- float fa;
-/*
- if (recursion){
- if (!didokee)
- printf("SB collision detected recursion. We will CRASH now!");
- didokee =1;
- return 0;
- }
- recursion =1;
-*/
- min_t = 200000;
-
- 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) {
- DerivedMesh *dm=NULL;
- int dmNeedsFree;
- Mesh *me= NULL;
- DispListMesh *disp_mesh = 0;
- MFace *mface;
- Object *copyob;
-
- /* do object level stuff */
- /* 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;
- copyob = ob;
-// if (ob->pd->flag & PDEFLE_DEFORM){// get colliding mesh from modifier stack
-// keep this option for debugging but IMHO this is not needed
- if (1){// get colliding mesh from modifier stack
-
- if(1) { // so maybe someone wants overkill to collide with subsurfed
- dm = mesh_get_derived_deform(copyob, &dmNeedsFree);
- } else {
- dm = mesh_get_derived_final(copyob, &dmNeedsFree);
- }
- }
-
- if (dm) {
- disp_mesh = dm->convertToDispListMesh(dm, 1);
- mface= disp_mesh->mface;
- a = disp_mesh->totface;
- }
- else {
- me = ob->data;
- mface= me->mface;
- a = me->totface;
- }
-
- /* use mesh*/
- while (a--) {
-
- /* Calculate the global co-ordinates of the vertices*/
- if (dm){
- dm->getVertCo(dm,mface->v1,nv1);
- Mat4MulVecfl(ob->obmat, nv1);
-
- dm->getVertCo(dm,mface->v2,nv2);
- Mat4MulVecfl(ob->obmat, nv2);
-
- dm->getVertCo(dm,mface->v3,nv3);
- Mat4MulVecfl(ob->obmat, nv3);
-
-
- if (mface->v4){
- dm->getVertCo(dm,mface->v4,nv4);
- Mat4MulVecfl(ob->obmat, nv4);
- }
- }
- else{
-
- VECCOPY(nv1,(me->mvert+(mface->v1))->co);
- Mat4MulVecfl(ob->obmat, nv1);
-
- VECCOPY(nv2,(me->mvert+(mface->v2))->co);
- Mat4MulVecfl(ob->obmat, nv2);
-
- VECCOPY(nv3,(me->mvert+(mface->v3))->co);
- Mat4MulVecfl(ob->obmat, nv3);
-
- if (mface->v4){
- VECCOPY(nv4,(me->mvert+(mface->v4))->co);
- Mat4MulVecfl(ob->obmat, nv4);
- }
-
- }
- 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
-
- Crossf(d_nvect, edge2, edge1);
- n_mag = Normalise(d_nvect);
- 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 ( 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[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;
- }
- }
- 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
-
- Crossf(d_nvect, edge2, edge1);
- n_mag = Normalise(d_nvect);
- 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 ( 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;
- }
- }
-
- }
- }
- 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;
- }
- }
-
- 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;
- 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++;
-
- }//while a
- /* give it away */
- if (disp_mesh) {
- displistmesh_free(disp_mesh);
- }
- if (dm) {
- if (dmNeedsFree) dm->release(dm);
- }
- } // if(ob->pd && ob->pd->deflect)
- }//if (base->object->type==OB_MESH && (base->lay & par_layer)) {
- base = base->next;
- } // while (base)
-
- if (mode == 1){ // face
-// recursion = 0;
- 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);
- }
- }
-// recursion = 0;
- return deflected;
-}
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index d29cd7e664f..429c4596781 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -77,9 +77,11 @@ variables on the UI for now
#include "BKE_object.h"
#include "BKE_softbody.h"
#include "BKE_utildefines.h"
+#include "BKE_DerivedMesh.h"
#include "BIF_editdeform.h"
+
/* ********** soft body engine ******* */
typedef struct BodyPoint {
@@ -336,6 +338,257 @@ static void free_softbody_intern(SoftBody *sb)
/* ************ dynamics ********** */
+int sb_detect_collision(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)
+{
+// static short recursion = 0;
+// static short didokee = 0;
+ Base *base;
+ Object *ob;
+ float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[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;
+ 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 innerfacethickness = -0.5f;
+ float outerfacethickness = 0.2f;
+ float ee = 5.0f;
+ float ff = 0.1f;
+ float fa;
+/*
+ if (recursion){
+ if (!didokee)
+ printf("SB collision detected recursion. We will CRASH now!");
+ didokee =1;
+ return 0;
+ }
+ recursion =1;
+*/
+ min_t = 200000;
+
+ 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) {
+ DerivedMesh *dm=NULL;
+ int dmNeedsFree;
+ Mesh *me= NULL;
+ DispListMesh *disp_mesh = 0;
+ MFace *mface;
+ Object *copyob;
+
+ /* do object level stuff */
+ /* 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;
+ copyob = ob;
+// if (ob->pd->flag & PDEFLE_DEFORM){// get colliding mesh from modifier stack
+// keep this option for debugging but IMHO this is not needed
+ if (1){// get colliding mesh from modifier stack
+
+ if(1) { // so maybe someone wants overkill to collide with subsurfed
+ dm = mesh_get_derived_deform(copyob, &dmNeedsFree);
+ } else {
+ dm = mesh_get_derived_final(copyob, &dmNeedsFree);
+ }
+ }
+
+ if (dm) {
+ disp_mesh = dm->convertToDispListMesh(dm, 1);
+ mface= disp_mesh->mface;
+ a = disp_mesh->totface;
+ }
+ else {
+ me = ob->data;
+ mface= me->mface;
+ a = me->totface;
+ }
+
+ /* use mesh*/
+ while (a--) {
+
+ /* Calculate the global co-ordinates of the vertices*/
+ if (dm){
+ dm->getVertCo(dm,mface->v1,nv1);
+ Mat4MulVecfl(ob->obmat, nv1);
+
+ dm->getVertCo(dm,mface->v2,nv2);
+ Mat4MulVecfl(ob->obmat, nv2);
+
+ dm->getVertCo(dm,mface->v3,nv3);
+ Mat4MulVecfl(ob->obmat, nv3);
+
+
+ if (mface->v4){
+ dm->getVertCo(dm,mface->v4,nv4);
+ Mat4MulVecfl(ob->obmat, nv4);
+ }
+ }
+ else{
+
+ VECCOPY(nv1,(me->mvert+(mface->v1))->co);
+ Mat4MulVecfl(ob->obmat, nv1);
+
+ VECCOPY(nv2,(me->mvert+(mface->v2))->co);
+ Mat4MulVecfl(ob->obmat, nv2);
+
+ VECCOPY(nv3,(me->mvert+(mface->v3))->co);
+ Mat4MulVecfl(ob->obmat, nv3);
+
+ if (mface->v4){
+ VECCOPY(nv4,(me->mvert+(mface->v4))->co);
+ Mat4MulVecfl(ob->obmat, nv4);
+ }
+
+ }
+ 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
+
+ Crossf(d_nvect, edge2, edge1);
+ n_mag = Normalise(d_nvect);
+ 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)){
+ 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;
+ }
+ }
+ 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
+
+ Crossf(d_nvect, edge2, edge1);
+ n_mag = Normalise(d_nvect);
+ 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)){
+ 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;
+ }
+ }
+
+ }
+ }
+ 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(LineIntersectsTriangle(opco, npco, nv1, nv2, nv3, &t) ) {
+ if (t < min_t) {
+ deflected = 1;
+ deflected_now = 1;
+ }
+ }
+
+ if (mface->v4) {
+ if( LineIntersectsTriangle(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;
+ 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++;
+
+ }//while a
+ /* give it away */
+ if (disp_mesh) {
+ displistmesh_free(disp_mesh);
+ }
+ if (dm) {
+ if (dmNeedsFree) dm->release(dm);
+ }
+ } // if(ob->pd && ob->pd->deflect)
+ }//if (base->object->type==OB_MESH && (base->lay & par_layer)) {
+ base = base->next;
+ } // while (base)
+
+ if (mode == 1){ // face
+// recursion = 0;
+ 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);
+ }
+ }
+// recursion = 0;
+ return deflected;
+}
/* aye this belongs to arith.c */
static void Vec3PlusStVec(float *v, float s, float *v1)
@@ -355,7 +608,7 @@ static int sb_deflect_face(Object *ob,float *actpos, float *futurepos,float *col
if (bounce) *bounce *= 1.5f;
- deflected= SoftBodyDetectCollision(s_actpos, s_futurepos, collisionpos,
+ deflected= sb_detect_collision(s_actpos, s_futurepos, collisionpos,
facenormal, cf, force , 1,
G.scene->r.cfra, ob->lay, ob);
return(deflected);