/**
* $Id:$
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* The contents of this file may be used under the terms of either the GNU
* General Public License Version 2 or later (the "GPL", see
* http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or
* later (the "BL", see http://www.blender.org/BL/ ) which has to be
* bought from the Blender Foundation to become active, in which case the
* above mentioned GPL option does not apply.
*
* The Original Code is Copyright (C) 2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
int intersect_dface_nocor(DFace *dface, struct Snijp *sn, float *oldloc, float *speed)
{
float ndist, labda, s, t, inploc, inpspeed;
int cox=0, coy=1;
if(dface->v3==0) return 0;
inpspeed= dface->no[0]*speed[0] + dface->no[1]*speed[1] + dface->no[2]*speed[2];
/* single sided! */
if(inpspeed < -TOLER) {
inploc= dface->no[0]*oldloc[0] + dface->no[1]*oldloc[1] + dface->no[2]*oldloc[2];
ndist= dface->dist - inploc; /* negatief! */
if(ndist>0.0) return 0;
labda= (ndist)/inpspeed; /* voor s-t */
/* labda is gegarandeerd > 0! (ndist<0.0) */
if(labda<sn->minlabda) return 0;
else if(labda> sn->labda) return 0;
if(dface->proj==1) coy= 2;
else if(dface->proj==2) {
cox= 1; coy= 2;
}
s= oldloc[cox] + labda*speed[cox];
t= oldloc[coy] + labda*speed[coy];
if( (dface->v2[cox] - s)*(dface->v2[coy] - dface->v1[coy]) -
(dface->v2[coy] - t)*(dface->v2[cox] - dface->v1[cox]) < 0.0 )
return 0;
if( (dface->v3[cox] - s)*(dface->v3[coy] - dface->v2[coy]) -
(dface->v3[coy] - t)*(dface->v3[cox] - dface->v2[cox])< 0.0 )
return 0;
if(dface->v4==0) {
if( (dface->v1[cox] - s)*(dface->v1[coy] - dface->v3[coy]) -
(dface->v1[coy] - t)*(dface->v1[cox] - dface->v3[cox])< 0.0 )
return 0;
}
else {
if( (dface->v4[cox] - s)*(dface->v4[coy] - dface->v3[coy]) -
(dface->v4[coy] - t)*(dface->v4[cox] - dface->v3[cox])< 0.0 )
return 0;
if( (dface->v1[cox] - s)*(dface->v1[coy] - dface->v4[coy]) -
(dface->v1[coy] - t)*(dface->v1[cox] - dface->v4[cox])< 0.0 )
return 0;
}
sn->labda= labda;
sn->inpspeed= inpspeed;
sn->face= dface;
return 1;
}
return 0;
}
#define S14MUL(a, b) ( ((a)*(b))>>14 )
#define DYNAFIX 16384
#define DYNAFIXF 16384.0
#define UNSURE (320<<14)
#define UNSURE1 (1024)
void isect_vert_conf(short *svec, float *vert)
{
svec[0]= (DYNAFIXF*vert[0]);
svec[1]= (DYNAFIXF*vert[1]);
svec[2]= (DYNAFIXF*vert[2]);
}
struct pSnijp {
int labda, minlabda, inpspeed;
pDFace *face;
MATRIX *obmat; /* als hier iets staat: ook doen! */
};
/* nieuwe methode: met correctie normaal!!! */
int psx_intersect_dface(pDFace *dface, struct pSnijp *sn, int *oldloc, short *speed)
{
int labda, labdacor, ndist, s, t, inploc, inpspeed;
int cox=0, coy=1;
int a, b;
if(dface->v3==0) return 0;
inpspeed= (dface->no[0]*speed[0] + dface->no[1]*speed[1] + dface->no[2]*speed[2]);
/* single sided! */
if(inpspeed < -160) {
inploc= (dface->no[0]*oldloc[0] + dface->no[1]*oldloc[1] + dface->no[2]*oldloc[2]);
ndist= (dface->dist - inploc);
/* test 1: mag je delen? */
if(ndist>=0 || (ndist+UNSURE) <= inpspeed) return 0;
labdacor= ( (ndist+UNSURE)<<4 )/(inpspeed>>10);
labda= (ndist<<4)/(inpspeed>>10);
/* debug test oftie nog leeft */
/* printf("fa %x lab %d min %d\n", dface, labdacor, sn->minlabda); */
/* dit is een soort interval-wiskunde */
/* deze twee regels zijn samen nodig: geval 1 afvangen */
if(labdacor<=sn->minlabda) {
if(labda<=sn->minlabda) return 0;
}
if(labdacor>=sn->labda) {
if(labda>=sn->labda) return 0;
/* voorkomt hobbelen */
}
if(dface->proj==1) coy= 2;
else if(dface->proj==2) {
cox= 1; coy= 2;
}
s= oldloc[cox] + S14MUL(labda, speed[cox]);
t= oldloc[coy] + S14MUL(labda, speed[coy]);
if( (dface->v2[cox] - s)*(dface->v2[coy] - dface->v1[coy]) <
(dface->v2[coy] - t)*(dface->v2[cox] - dface->v1[cox]) )
return 0;
if( (dface->v3[cox] - s)*(dface->v3[coy] - dface->v2[coy]) <
(dface->v3[coy] - t)*(dface->v3[cox] - dface->v2[cox]) )
return 0;
if(dface->v4==0) {
if( (dface->v1[cox] - s)*(dface->v1[coy] - dface->v3[coy]) <
(dface->v1[coy] - t)*(dface->v1[cox] - dface->v3[cox]) )
return 0;
}
else {
if( (dface->v4[cox] - s)*(dface->v4[coy] - dface->v3[coy]) <
(dface->v4[coy] - t)*(dface->v4[cox] - dface->v3[cox]) )
return 0;
if( (dface->v1[cox] - s)*(dface->v1[coy] - dface->v4[coy]) <
(dface->v1[coy] - t)*(dface->v1[cox] - dface->v4[cox]) )
return 0;
}
sn->labda= labdacor;
sn->inpspeed= (inpspeed>>14);
sn->face= dface;
return 1;
}
return 0;
}
int intersect_dface_test(DFace *dface, struct Snijp *sn, float *oldloc, float *speed)
/* testversie voor fixpoint math */
{
pDFace *pdface, rtdf;
struct pSnijp psn;
float labda, s, t, inploc, inpspeed;
int ilabda, is, it, iinploc, iinpspeed;
int a, b, cox=0, coy=1, ioldloc[3];
short verts[4][3], ispeed[3];
if(dface->v3==0) return 0;
/* **************** CONVERT *********** */
pdface= &rtdf;
pdface->v1= verts[0]; isect_vert_conf(verts[0], dface->v1);
pdface->v2= verts[1]; isect_vert_conf(verts[1], dface->v2);
pdface->v3= verts[2]; isect_vert_conf(verts[2], dface->v3);
if(dface->v4) {
pdface->v4= verts[3]; isect_vert_conf(verts[3], dface->v4);
}
else pdface->v4= 0;
pdface->dist= (DYNAFIXF*(DYNAFIXF*dface->dist));
pdface->proj= dface->proj;
pdface->no[0]= (DYNAFIXF*dface->no[0]);
pdface->no[1]= (DYNAFIXF*dface->no[1]);
pdface->no[2]= (DYNAFIXF*dface->no[2]);
isect_vert_conf(ispeed, speed);
ioldloc[0]= (DYNAFIXF*oldloc[0]);
ioldloc[1]= (DYNAFIXF*oldloc[1]);
ioldloc[2]= (DYNAFIXF*oldloc[2]);
psn.labda= (DYNAFIXF*sn->labda);
psn.minlabda= (DYNAFIXF*sn->minlabda);
psn.inpspeed= (DYNAFIXF*sn->inpspeed);
/************************* */
if( psx_intersect_dface(pdface, &psn, ioldloc, ispeed) ) {
sn->labda= ((float)psn.labda)/DYNAFIXF;
sn->minlabda= ((float)psn.minlabda)/DYNAFIXF;
sn->inpspeed= ((float)psn.inpspeed)/DYNAFIXF;
sn->face= dface;
return 1;
}
return 0;
}