home *** CD-ROM | disk | FTP | other *** search
- /*!
- \file intersection.cpp
- \author Karsten Schwenk
-
- See header for description (intersection.h).
- */
-
-
- #include "intersection.h"
-
- #include <math.h>
- //#include <stdio.h>
-
- #define INTERSECTION_EPSILON 0.001
-
- bool pointIntersectsPlane(vec3_t point, vec4_t plane){
- return fabs(vectorDotP3d(point, plane)-plane[3]) < INTERSECTION_EPSILON;
- }
-
- bool pointIntersectsTriangle(vec3_t point, vec3_t p1, vec3_t p2, vec3_t p3){
- vec4_t plane;
- vec3_t p1p2, p1p3, p2p3;
- vec3_t p1point, p2point;//, p3point;
- vec3_t c1,c2;
-
- vectorSub3d(p2, p1, p1p2);
- vectorSub3d(p3, p1, p1p3);
- vectorSub3d(p3, p2, p2p3);
-
- vectorCrossP3d(p1p2, p1p3, plane);
- vectorNormalize3d(plane, plane);
- plane[3]=vectorDotP3d(p1, plane);
-
- if(fabs(vectorDotP3d(point, plane)-plane[3]) > INTERSECTION_EPSILON)
- return false;
-
- vectorSub3d(point, p1, p1point);
- vectorCrossP3d(p1p2, p1p3, c1);
- vectorCrossP3d(p1p2, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- // vectorSub3d(point, p1, p1point);
- vectorCrossP3d(p1p3, p1p2, c1);
- vectorCrossP3d(p1p3, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
-
- vectorScale3d(-1.0f, p1p2, p1p2);
- vectorSub3d(point, p2, p2point);
- vectorCrossP3d(p2p3, p1p2, c1);
- vectorCrossP3d(p2p3, p2point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- return true;
- }
-
- bool pointIntersectsSphere(vec3_t point, vec3_t center, float radius){
- return vectorPointDistance3d(point, center) <= radius;
- }
-
- bool pointIntersectsCube(vec3_t point, vec3_t center, float edgelength){
- double l=edgelength*0.5;
-
- return (point[0]>center[0]-l && point[0]<center[0]+l
- && point[1]>center[1]-l && point[1]<center[1]+l
- && point[2]>center[2]-l && point[2]<center[2]+l);
- }
- bool pointIntersectsBox(vec3_t point, vec3_t center, vec3_t edgelengths){
- double l0=edgelengths[0]*0.5;
- double l1=edgelengths[1]*0.5;
- double l2=edgelengths[2]*0.5;
-
- return (point[0]>center[0]-l0 && point[0]<center[0]+l0
- && point[1]>center[1]-l1 && point[1]<center[1]+l1
- && point[2]>center[2]-l2 && point[2]<center[2]+l2);
- }
- bool pointIntersectsAABB(vec3_t point, vec3_t min, vec3_t max){
-
- return (point[0]>=min[0] && point[0]<=max[0]
- && point[1]>=min[1] && point[1]<=max[1]
- && point[2]>=min[2] && point[2]<=max[2]);
- }
-
- bool lineIntersectsPlane(vec3_t pos, vec3_t dir, vec4_t plane){
- double xd=vectorDotP3d(plane, dir);
-
- return (xd!=0.0);
- }
-
- bool lineIntersectsPlane(vec3_t pos, vec3_t dir, vec4_t plane, float* distance, vec3_t hitpoint){
- double xd=vectorDotP3d(plane, dir);
-
- if(xd==0.0)
- return false;
-
- *distance=(float)( (plane[3]-vectorDotP3d(plane, pos))/xd );
- vectorMA3d(pos, *distance, dir, hitpoint);
-
- return true;
- }
-
- bool lineIntersectsTriangle(vec3_t pos, vec3_t dir, vec3_t p1, vec3_t p2, vec3_t p3){
- vec4_t plane;
- vec3_t p1p2, p1p3, p2p3;
- vec3_t p1point, p2point;
- vec3_t c1,c2;
- vec3_t hitpoint;
-
- vectorSub3d(p2, p1, p1p2);
- vectorSub3d(p3, p1, p1p3);
- vectorSub3d(p3, p2, p2p3);
-
- vectorCrossP3d(p1p2, p1p3, plane);
- vectorNormalize3d(plane, plane);
- plane[3]=vectorDotP3d(p1, plane);
-
- double xd=vectorDotP3d(plane, dir);
-
- if(xd==0.0)
- return false;
-
- float distance=(float)( (plane[3]-vectorDotP3d(plane, pos))/xd );
- vectorMA3d(pos, distance, dir, hitpoint);
-
- // check if hitpoint is in triangle
- vectorSub3d(hitpoint, p1, p1point);
- vectorCrossP3d(p1p2, p1p3, c1);
- vectorCrossP3d(p1p2, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- // vectorSub3d(point, p1, p1point);
- vectorCrossP3d(p1p3, p1p2, c1);
- vectorCrossP3d(p1p3, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- vectorScale3d(-1.0f, p1p2, p1p2);
- vectorSub3d(hitpoint, p2, p2point);
- vectorCrossP3d(p2p3, p1p2, c1);
- vectorCrossP3d(p2p3, p2point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- return true;
- }
-
- bool lineIntersectsTriangle(vec3_t pos, vec3_t dir, vec3_t p1, vec3_t p2, vec3_t p3, float* distance, vec3_t hitpoint){
- vec4_t plane;
- vec3_t p1p2, p1p3, p2p3;
- vec3_t p1point, p2point;
- vec3_t c1,c2;
-
- vectorSub3d(p2, p1, p1p2);
- vectorSub3d(p3, p1, p1p3);
- vectorSub3d(p3, p2, p2p3);
-
- vectorCrossP3d(p1p2, p1p3, plane);
- vectorNormalize3d(plane, plane);
- plane[3]=vectorDotP3d(p1, plane);
-
- double xd=vectorDotP3d(plane, dir);
-
- if(xd==0.0)
- return false;
-
- *distance=(float)( (plane[3]-vectorDotP3d(plane, pos))/xd );
- vectorMA3d(pos, *distance, dir, hitpoint);
-
- // check if hitpoint is in triangle
- vectorSub3d(hitpoint, p1, p1point);
- vectorCrossP3d(p1p2, p1p3, c1);
- vectorCrossP3d(p1p2, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- // vectorSub3d(point, p1, p1point);
- vectorCrossP3d(p1p3, p1p2, c1);
- vectorCrossP3d(p1p3, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- vectorScale3d(-1.0f, p1p2, p1p2);
- vectorSub3d(hitpoint, p2, p2point);
- vectorCrossP3d(p2p3, p1p2, c1);
- vectorCrossP3d(p2p3, p2point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- return true;
- }
-
- bool lineIntersectsSphere(vec3_t pos, vec3_t dir, vec3_t center, float radius){
- vec3_t h;
- vectorSub3d(pos, center, h);
- double a=vectorDotP3d(dir, dir);
- double b=2.0f*vectorDotP3d(dir, h);
- double c=radius+vectorDotP3d(h, h);
-
- double d=b*b - 4*a*c;
-
- return (d>=0.0);
- }
-
- bool lineIntersectsSphere(vec3_t pos, vec3_t dir, vec3_t center, float radius, float* distance, vec3_t hitpoint){
- vec3_t h;
- vectorSub3d(pos, center, h);
- double a=vectorDotP3d(dir, dir);
- double b=2.0f*vectorDotP3d(dir, h);
- double c=radius+vectorDotP3d(h, h);
-
- double d=b*b - 4*a*c;
-
- if(d<0.0)
- return false;
-
- double x1=(-b+sqrt(d))/(2*a);
- double x2=(-b-sqrt(d))/(2*a);
-
- *distance=(float)( x1<x2 ? x1 : x2 );
- vectorMA3d(pos, *distance, dir, hitpoint);
-
- return true;
- }
-
- bool lineIntersectsCube(vec3_t pos, vec3_t dir, vec3_t center, float edgelength){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelength, center[1]-edgelength, center[2]-edgelength, min);
- vectorInit3d(center[0]+edgelength, center[1]+edgelength, center[2]+edgelength, max);
-
- return lineIntersectsAABB(pos, dir, min, max);
- }
-
- bool lineIntersectsCube(vec3_t pos, vec3_t dir, vec3_t center, float edgelength, float* distance, vec3_t hitpoint){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelength, center[1]-edgelength, center[2]-edgelength, min);
- vectorInit3d(center[0]+edgelength, center[1]+edgelength, center[2]+edgelength, max);
-
- return lineIntersectsAABB(pos, dir, min, max, distance, hitpoint);
- }
-
- bool lineIntersectsBox(vec3_t pos, vec3_t dir, vec3_t center, vec3_t edgelengths){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelengths[0], center[1]-edgelengths[1], center[2]-edgelengths[2], min);
- vectorInit3d(center[0]+edgelengths[0], center[1]+edgelengths[1], center[2]+edgelengths[2], max);
-
- return lineIntersectsAABB(pos, dir, min, max);
- }
-
- bool lineIntersectsBox(vec3_t pos, vec3_t dir, vec3_t center, vec3_t edgelengths, float* distance, vec3_t hitpoint){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelengths[0], center[1]-edgelengths[1], center[2]-edgelengths[2], min);
- vectorInit3d(center[0]+edgelengths[0], center[1]+edgelengths[1], center[2]+edgelengths[2], max);
-
- return lineIntersectsAABB(pos, dir, min, max, distance, hitpoint);
- }
-
- bool lineIntersectsAABB(vec3_t pos, vec3_t dir, vec3_t min, vec3_t max){
- vec4_t plane;
- vec3_t hitpoint;
- float distance;
-
- vectorInit3d(1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON // THINKABOUTME: geht auch ohne EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
- vectorInit3d(-1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
-
- vectorInit3d(0.0f, 1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
- vectorInit3d(0.0f, -1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
-
- vectorInit3d(0.0f, 0.0f, 1.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON){
- return true;
- }
- }
- vectorInit3d(0.0f, 0.0f, -1.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON){
- return true;
- }
- }
-
- return false;
- }
-
- bool lineIntersectsAABB(vec3_t pos, vec3_t dir, vec3_t min, vec3_t max, float* distance, vec3_t hitpoint){
- vec4_t plane;
- vec3_t hp;
- float d;
- *distance=FLT_MAX;
-
- vectorInit3d(1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON // THINKABOUTME: geht auch ohne EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON){
- *distance = d < *distance ? d : *distance;
- }
- }
- vectorInit3d(-1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON){
- *distance = d < *distance ? d : *distance;
- }
- }
-
- vectorInit3d(0.0f, 1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON){
- *distance = d < *distance ? d : *distance;
- }
- }
- vectorInit3d(0.0f, -1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON){
- *distance = d < *distance ? d : *distance;
- }
- }
-
- vectorInit3d(0.0f, 0.0f, 1.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON
- && hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON){
- *distance = d < *distance ? d : *distance;
- }
- }
- vectorInit3d(0.0f, 0.0f, -1.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON
- && hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON){
- *distance = d < *distance ? d : *distance;
- }
- }
-
- if(*distance < FLT_MAX){
- vectorMA3d(pos, *distance, dir, hitpoint);
- return true;
- }else{
- return false;
- }
- }
-
-
-
-
- bool linesegmentIntersectsPlane(vec3_t pos1, vec3_t pos2, vec4_t plane){
- vec3_t dir;
- vectorSub3d(pos2, pos1, dir);
-
- double xd=vectorDotP3d(plane, dir);
-
- if(xd==0.0)
- return false;
-
- double distance= (plane[3]-vectorDotP3d(plane, pos1))/xd;
-
- return (distance>=0.0 && distance<=1.0);
- }
-
- bool linesegmentIntersectsPlane(vec3_t pos1, vec3_t pos2, vec4_t plane, float* distance, vec3_t hitpoint){
- vec3_t dir;
- vectorSub3d(pos2, pos1, dir);
-
- double xd=vectorDotP3d(plane, dir);
-
- if(xd==0.0)
- return false;
-
- *distance=(float)( (plane[3]-vectorDotP3d(plane, pos1))/xd );
- if(*distance>=0.0 && *distance<=1.0){
- vectorMA3d(pos1, *distance, dir, hitpoint);
- return true;
- }else{
- return false;
- }
- }
-
- bool linesegmentIntersectsTriangle(vec3_t pos1, vec3_t pos2, vec3_t p1, vec3_t p2, vec3_t p3){
- vec3_t dir;
- vec4_t plane;
- vec3_t p1p2, p1p3, p2p3;
- vec3_t p1point, p2point;
- vec3_t c1,c2;
- vec3_t hitpoint;
-
- vectorSub3d(pos2, pos1, dir);
-
- vectorSub3d(p2, p1, p1p2);
- vectorSub3d(p3, p1, p1p3);
- vectorSub3d(p3, p2, p2p3);
-
- vectorCrossP3d(p1p2, p1p3, plane);
- vectorNormalize3d(plane, plane);
- plane[3]=vectorDotP3d(p1, plane);
-
- double xd=vectorDotP3d(plane, dir);
-
- if(xd==0.0)
- return false;
-
- float distance=(float)( (plane[3]-vectorDotP3d(plane, pos1))/xd );
- if(distance<0.0 || distance>1.0)
- return false;
-
- vectorMA3d(pos1, distance, dir, hitpoint);
-
- // check if hitpoint is in triangle
- vectorSub3d(hitpoint, p1, p1point);
- vectorCrossP3d(p1p2, p1p3, c1);
- vectorCrossP3d(p1p2, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- // vectorSub3d(point, p1, p1point);
- vectorCrossP3d(p1p3, p1p2, c1);
- vectorCrossP3d(p1p3, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- vectorScale3d(-1.0f, p1p2, p1p2);
- vectorSub3d(hitpoint, p2, p2point);
- vectorCrossP3d(p2p3, p1p2, c1);
- vectorCrossP3d(p2p3, p2point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- return true;
- }
-
- bool linesegmentIntersectsTriangle(vec3_t pos1, vec3_t pos2, vec3_t p1, vec3_t p2, vec3_t p3, float* distance, vec3_t hitpoint){
- vec3_t dir;
- vec4_t plane;
- vec3_t p1p2, p1p3, p2p3;
- vec3_t p1point, p2point;
- vec3_t c1,c2;
-
- vectorSub3d(pos2, pos1, dir);
-
- vectorSub3d(p2, p1, p1p2);
- vectorSub3d(p3, p1, p1p3);
- vectorSub3d(p3, p2, p2p3);
-
- vectorCrossP3d(p1p2, p1p3, plane);
- vectorNormalize3d(plane, plane);
- plane[3]=vectorDotP3d(p1, plane);
-
- double xd=vectorDotP3d(plane, dir);
-
- if(xd==0.0)
- return false;
-
- *distance=(float)( (plane[3]-vectorDotP3d(plane, pos1))/xd );
- if(*distance<0.0 || *distance>1.0)
- return false;
-
- vectorMA3d(pos1, *distance, dir, hitpoint);
-
- // check if hitpoint is in triangle
- vectorSub3d(hitpoint, p1, p1point);
- vectorCrossP3d(p1p2, p1p3, c1);
- vectorCrossP3d(p1p2, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- // vectorSub3d(point, p1, p1point);
- vectorCrossP3d(p1p3, p1p2, c1);
- vectorCrossP3d(p1p3, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- vectorScale3d(-1.0f, p1p2, p1p2);
- vectorSub3d(hitpoint, p2, p2point);
- vectorCrossP3d(p2p3, p1p2, c1);
- vectorCrossP3d(p2p3, p2point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- return true;
- }
-
- bool linesegmentIntersectsSphere(vec3_t pos1, vec3_t pos2, vec3_t center, float radius){
- if(vectorPointDistance3d(pos1, center) <= radius || vectorPointDistance3d(pos1, center) <= radius)
- return true;
-
- vec3_t dir;
- vectorSub3d(pos2, pos1, dir);
-
- vec3_t h;
- vectorSub3d(pos1, center, h);
- double a=vectorDotP3d(dir, dir);
- double b=2.0f*vectorDotP3d(dir, h);
- double c=radius+vectorDotP3d(h, h);
-
- double d=b*b - 4*a*c;
-
- if(d<0.0)
- return false;
-
- double x1=(-b+sqrt(d))/(2*a);
- double x2=(-b-sqrt(d))/(2*a);
-
- return ( (x1>=0.0 && x1<=1.0) || ( x2>=0.0 && x2<=1.0) );
-
- }
-
- bool linesegmentIntersectsSphere(vec3_t pos1, vec3_t pos2, vec3_t center, float radius, float* distance, vec3_t hitpoint){
- vec3_t dir;
- vectorSub3d(pos2, pos1, dir);
-
- vec3_t h;
- vectorSub3d(pos1, center, h);
- double a=vectorDotP3d(dir, dir);
- double b=2.0f*vectorDotP3d(dir, h);
- double c=radius+vectorDotP3d(h, h);
-
- double d=b*b - 4*a*c;
-
- if(d<0.0)
- return false;
-
- double x1=(-b+sqrt(d))/(2*a);
- double x2=(-b-sqrt(d))/(2*a);
-
- if(x1>=0.0 && x1<=1.0 && x2>=0.0 && x2<=1.0){
- *distance=(float)( x1 < x2 ? x1 : x2 );
- }else if(x1>=0.0 && x1<=1.0){
- *distance=(float)( x1 );
- }else if(x2>=0.0 && x2<=1.0){
- *distance=(float)( x2 );
- }else{
- // check if both points are inside the sphere
- if(vectorPointDistance3d(pos1, center) <= radius && vectorPointDistance3d(pos1, center) <= radius){
- return true; // THINKABOUTME: besonderer Rⁿckgabewert?? - z.B. distance=0.0??
- }else{
- return false;
- }
- }
-
- vectorMA3d(pos1, *distance, dir, hitpoint);
- return true;
-
- }
-
- bool linesegmentIntersectsCube(vec3_t pos1, vec3_t pos2, vec3_t center, float edgelength){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelength, center[1]-edgelength, center[2]-edgelength, min);
- vectorInit3d(center[0]+edgelength, center[1]+edgelength, center[2]+edgelength, max);
-
- return linesegmentIntersectsAABB(pos1, pos2, min, max);
- }
-
- bool linesegmentIntersectsCube(vec3_t pos1, vec3_t pos2, vec3_t center, float edgelength, float* distance, vec3_t hitpoint){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelength, center[1]-edgelength, center[2]-edgelength, min);
- vectorInit3d(center[0]+edgelength, center[1]+edgelength, center[2]+edgelength, max);
-
- return linesegmentIntersectsAABB(pos1, pos2, min, max, distance, hitpoint);
- }
-
- bool linesegmentIntersectsBox(vec3_t pos1, vec3_t pos2, vec3_t center, vec3_t edgelengths){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelengths[0], center[1]-edgelengths[1], center[2]-edgelengths[2], min);
- vectorInit3d(center[0]+edgelengths[0], center[1]+edgelengths[1], center[2]+edgelengths[2], max);
-
- return linesegmentIntersectsAABB(pos1, pos2, min, max);
- }
-
- bool linesegmentIntersectsBox(vec3_t pos1, vec3_t pos2, vec3_t center, vec3_t edgelengths, float* distance, vec3_t hitpoint){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelengths[0], center[1]-edgelengths[1], center[2]-edgelengths[2], min);
- vectorInit3d(center[0]+edgelengths[0], center[1]+edgelengths[1], center[2]+edgelengths[2], max);
-
- return linesegmentIntersectsAABB(pos1, pos2, min, max, distance, hitpoint);
- }
-
- bool linesegmentIntersectsAABB(vec3_t pos1, vec3_t pos2, vec3_t min, vec3_t max){
- vec4_t plane;
- vec3_t hitpoint;
- float distance;
- vec3_t dir;
- vectorSub3d(pos2, pos1, dir);
-
- if(pointIntersectsAABB(pos1, min, max) || pointIntersectsAABB(pos2, min, max)) // one point in AABB
- return true;
-
- vectorInit3d(1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON // THINKABOUTME: geht auch ohne EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON
- && distance>=0.0 && distance<=1.0){
- return true;
- }
- }
- vectorInit3d(-1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON
- && distance>=0.0 && distance<=1.0){
- return true;
- }
- }
-
- vectorInit3d(0.0f, 1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON
- && distance>=0.0 && distance<=1.0){
- return true;
- }
- }
- vectorInit3d(0.0f, -1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON
- && distance>=0.0 && distance<=1.0){
- return true;
- }
- }
-
- vectorInit3d(0.0f, 0.0f, 1.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && distance>=0.0 && distance<=1.0){
- return true;
- }
- }
- vectorInit3d(0.0f, 0.0f, -1.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && distance>=0.0 && distance<=1.0){
- return true;
- }
- }
-
- return false;
- }
-
- bool linesegmentIntersectsAABB(vec3_t pos1, vec3_t pos2, vec3_t min, vec3_t max, float* distance, vec3_t hitpoint){
- vec4_t plane;
- vec3_t hp;
- float d;
- vec3_t dir;
- vectorSub3d(pos2, pos1, dir);
-
- if(pointIntersectsAABB(pos1, min, max)){ // startPoint in AABB -> instant intersection
- *distance=0.0f;
- vectorCopy3d(pos1, hitpoint);
- return true;
- }
-
- *distance=FLT_MAX;
-
- vectorInit3d(1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON // THINKABOUTME: geht auch ohne EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON
- && d>=0.0 && d<=1.0){
- *distance = d < *distance ? d : *distance;
- }
- }
- vectorInit3d(-1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON
- && d>=0.0 && d<=1.0){
- *distance = d < *distance ? d : *distance;
- }
- }
-
- vectorInit3d(0.0f, 1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &d, hp)){
- if(hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON
- && d>=0.0 && d<=1.0){
- *distance = d < *distance ? d : *distance;
- }
- }
- vectorInit3d(0.0f, -1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &d, hp)){
- if(hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON
- && d>=0.0 && d<=1.0){
- *distance = d < *distance ? d : *distance;
- }
- }
-
- vectorInit3d(0.0f, 0.0f, 1.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON
- && hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON
- && d>=0.0 && d<=1.0){
- *distance = d < *distance ? d : *distance;
- }
- }
- vectorInit3d(0.0f, 0.0f, -1.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos1, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON
- && hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON
- && d>=0.0 && d<=1.0){
- *distance = d < *distance ? d : *distance;
- }
- }
-
- if(*distance < FLT_MAX){
- vectorMA3d(pos1, *distance, dir, hitpoint);
- return true;
- }else{
- return false;
- }
- }
-
-
-
-
- bool rayIntersectsPlane(vec3_t pos, vec3_t dir, vec4_t plane){
- double xd=vectorDotP3d(plane, dir);
-
- if(xd==0.0)
- return false;
-
- return (plane[3]-vectorDotP3d(plane, pos))/xd >= 0.0;
- }
-
- bool rayIntersectsPlane(vec3_t pos, vec3_t dir, vec4_t plane, float* distance, vec3_t hitpoint){
- double xd=vectorDotP3d(plane, dir);
-
- if(xd==0.0)
- return false;
-
- *distance=(float)( (plane[3]-vectorDotP3d(plane, pos))/xd );
- if(*distance>=0.0){
- vectorMA3d(pos, *distance, dir, hitpoint);
- return true;
- }else{
- return false;
- }
- }
-
- bool rayIntersectsTriangle(vec3_t pos, vec3_t dir, vec3_t p1, vec3_t p2, vec3_t p3){
- vec4_t plane;
- vec3_t p1p2, p1p3, p2p3;
- vec3_t p1point, p2point;
- vec3_t c1,c2;
- vec3_t hitpoint;
-
- vectorSub3d(p2, p1, p1p2);
- vectorSub3d(p3, p1, p1p3);
- vectorSub3d(p3, p2, p2p3);
-
- vectorCrossP3d(p1p2, p1p3, plane);
- vectorNormalize3d(plane, plane);
- plane[3]=vectorDotP3d(p1, plane);
-
- double xd=vectorDotP3d(plane, dir);
-
- if(xd==0.0)
- return false;
-
- float distance=(float)( (plane[3]-vectorDotP3d(plane, pos))/xd );
- if(distance<0.0)
- return false;
-
- vectorMA3d(pos, distance, dir, hitpoint);
-
- // check if hitpoint is in triangle
- vectorSub3d(hitpoint, p1, p1point);
- vectorCrossP3d(p1p2, p1p3, c1);
- vectorCrossP3d(p1p2, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- // vectorSub3d(point, p1, p1point);
- vectorCrossP3d(p1p3, p1p2, c1);
- vectorCrossP3d(p1p3, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- vectorScale3d(-1.0f, p1p2, p1p2);
- vectorSub3d(hitpoint, p2, p2point);
- vectorCrossP3d(p2p3, p1p2, c1);
- vectorCrossP3d(p2p3, p2point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- return true;
- }
-
- bool rayIntersectsTriangle(vec3_t pos, vec3_t dir, vec3_t p1, vec3_t p2, vec3_t p3, float* distance, vec3_t hitpoint){
- vec4_t plane;
- vec3_t p1p2, p1p3, p2p3;
- vec3_t p1point, p2point;
- vec3_t c1,c2;
-
- vectorSub3d(p2, p1, p1p2);
- vectorSub3d(p3, p1, p1p3);
- vectorSub3d(p3, p2, p2p3);
-
- vectorCrossP3d(p1p2, p1p3, plane);
- vectorNormalize3d(plane, plane);
- plane[3]=vectorDotP3d(p1, plane);
-
- double xd=vectorDotP3d(plane, dir);
-
- if(xd==0.0)
- return false;
-
- *distance=(float)( (plane[3]-vectorDotP3d(plane, pos))/xd );
- if(*distance<0.0)
- return false;
-
- vectorMA3d(pos, *distance, dir, hitpoint);
-
- // check if hitpoint is in triangle
- vectorSub3d(hitpoint, p1, p1point);
- vectorCrossP3d(p1p2, p1p3, c1);
- vectorCrossP3d(p1p2, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- // vectorSub3d(point, p1, p1point);
- vectorCrossP3d(p1p3, p1p2, c1);
- vectorCrossP3d(p1p3, p1point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- vectorScale3d(-1.0f, p1p2, p1p2);
- vectorSub3d(hitpoint, p2, p2point);
- vectorCrossP3d(p2p3, p1p2, c1);
- vectorCrossP3d(p2p3, p2point, c2);
- if(vectorDotP3d(c1,c2) < 0.0)
- return false;
-
- return true;
-
- }
-
- bool rayIntersectsSphere(vec3_t pos, vec3_t dir, vec3_t center, float radius){
-
- vec3_t h;
- vectorSub3d(pos, center, h);
- double a=vectorDotP3d(dir, dir);
- double b=2.0f*vectorDotP3d(dir, h);
- double c=radius+vectorDotP3d(h, h);
-
- double d=b*b - 4*a*c;
-
- if(d<0.0)
- return false;
-
- double x1=(-b+sqrt(d))/(2*a);
- double x2=(-b-sqrt(d))/(2*a);
-
- return ( (x1>=0.0) || ( x2>=0.0) );
- }
-
- bool rayIntersectsSphere(vec3_t pos, vec3_t dir, vec3_t center, float radius, float* distance, vec3_t hitpoint){
- vec3_t h;
- vectorSub3d(pos, center, h);
- double a=vectorDotP3d(dir, dir);
- double b=2.0f*vectorDotP3d(dir, h);
- double c=radius+vectorDotP3d(h, h);
-
- double d=b*b - 4*a*c;
-
- if(d<0.0)
- return false;
-
- double x1=(-b+sqrt(d))/(2*a);
- double x2=(-b-sqrt(d))/(2*a);
-
- if(x1>=0.0 && x2>=0.0){ // THINKABOUTME: besser machen
- *distance=(float)( x1 < x2 ? x1 : x2 );
- }else if(x1>=0.0){
- *distance=(float)( x1 );
- }else if(x2>=0.0){
- *distance=(float)( x2 );
- }else{
- return false;
- }
-
- vectorMA3d(pos, *distance, dir, hitpoint);
- return true;
- }
-
- bool rayIntersectsCube(vec3_t pos, vec3_t dir, vec3_t center, float edgelength){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelength, center[1]-edgelength, center[2]-edgelength, min);
- vectorInit3d(center[0]+edgelength, center[1]+edgelength, center[2]+edgelength, max);
-
- return rayIntersectsAABB(pos, dir, min, max);
- }
-
- bool rayIntersectsCube(vec3_t pos, vec3_t dir, vec3_t center, float edgelength, float* distance, vec3_t hitpoint){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelength, center[1]-edgelength, center[2]-edgelength, min);
- vectorInit3d(center[0]+edgelength, center[1]+edgelength, center[2]+edgelength, max);
-
- return rayIntersectsAABB(pos, dir, min, max, distance, hitpoint);
- }
-
- bool rayIntersectsBox(vec3_t pos, vec3_t dir, vec3_t center, vec3_t edgelengths){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelengths[0], center[1]-edgelengths[1], center[2]-edgelengths[2], min);
- vectorInit3d(center[0]+edgelengths[0], center[1]+edgelengths[1], center[2]+edgelengths[2], max);
-
- return rayIntersectsAABB(pos, dir, min, max);
- }
-
- bool rayIntersectsBox(vec3_t pos, vec3_t dir, vec3_t center, vec3_t edgelengths, float* distance, vec3_t hitpoint){
- vec3_t min, max;
- vectorInit3d(center[0]-edgelengths[0], center[1]-edgelengths[1], center[2]-edgelengths[2], min);
- vectorInit3d(center[0]+edgelengths[0], center[1]+edgelengths[1], center[2]+edgelengths[2], max);
-
- return rayIntersectsAABB(pos, dir, min, max, distance, hitpoint);
- }
-
- bool rayIntersectsAABB(vec3_t pos, vec3_t dir, vec3_t min, vec3_t max){
- vec4_t plane;
- vec3_t hitpoint;
- float distance;
-
- vectorInit3d(1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON // THINKABOUTME: geht auch ohne EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON
- && distance>=0.0){
- return true;
- }
- }
- vectorInit3d(-1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON
- && distance>=0.0){
- return true;
- }
- }
-
- vectorInit3d(0.0f, 1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON
- && distance>=0.0){
- return true;
- }
- }
- vectorInit3d(0.0f, -1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON
- && distance>=0.0){
- return true;
- }
- }
-
- vectorInit3d(0.0f, 0.0f, 1.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && distance>=0.0){
- return true;
- }
- }
- vectorInit3d(0.0f, 0.0f, -1.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && distance>=0.0){
- return true;
- }
- }
-
- return false;
- }
-
- bool rayIntersectsAABB(vec3_t pos, vec3_t dir, vec3_t min, vec3_t max, float* distance, vec3_t hitpoint){
- vec4_t plane;
- vec3_t hp;
- float d;
-
- *distance=FLT_MAX;
-
- vectorInit3d(1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON // THINKABOUTME: geht auch ohne EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON
- && d>=0.0){
- *distance = d < *distance ? d : *distance;
- }
- }
- vectorInit3d(-1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON
- && d>=0.0){
- *distance = d < *distance ? d : *distance;
- }
- }
-
- vectorInit3d(0.0f, 1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON
- && d>=0.0){
- *distance = d < *distance ? d : *distance;
- }
- }
- vectorInit3d(0.0f, -1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON
- && hp[2]>min[2]-INTERSECTION_EPSILON && hp[2]<max[2]+INTERSECTION_EPSILON
- && d>=0.0){
- *distance = d < *distance ? d : *distance;
- }
- }
-
- vectorInit3d(0.0f, 0.0f, 1.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON
- && hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON
- && d>=0.0){
- *distance = d < *distance ? d : *distance;
- }
- }
- vectorInit3d(0.0f, 0.0f, -1.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(lineIntersectsPlane(pos, dir, plane, &d, hp)){
- if(hp[1]>min[1]-INTERSECTION_EPSILON && hp[1]<max[1]+INTERSECTION_EPSILON
- && hp[0]>min[0]-INTERSECTION_EPSILON && hp[0]<max[0]+INTERSECTION_EPSILON
- && d>=0.0){
- *distance = d < *distance ? d : *distance;
- }
- }
-
- if(*distance < FLT_MAX){
- vectorMA3d(pos, *distance, dir, hitpoint);
- return true;
- }else{
- return false;
- }
- }
-
-
- bool triangleIntersectsTriangle(vec3_t p1_1, vec3_t p1_2, vec3_t p1_3, vec3_t p2_1, vec3_t p2_2, vec3_t p2_3){
- return false;
- }
-
- bool triangleIntersectsSphere(vec3_t p1, vec3_t p2, vec3_t p3, vec3_t center, float radius){
- if(vectorPointDistance3d(p1, center) <= radius)
- return true;
- if(vectorPointDistance3d(p2, center) <= radius)
- return true;
- if(vectorPointDistance3d(p3, center) <= radius)
- return true;
-
- if(linesegmentIntersectsSphere(p1, p2, center, radius))
- return true;
- if(linesegmentIntersectsSphere(p2, p3, center, radius))
- return true;
- if(linesegmentIntersectsSphere(p3, p1, center, radius))
- return true;
-
- // FIXME: dreieck umgibt kugel!
- return false;
- }
-
- bool triangleIntersectsCube(vec3_t p1, vec3_t p2, vec3_t p3, vec3_t center, float edgelength){
- vec3_t min, max;
-
- vectorInit3d(center[0]-edgelength, center[1]-edgelength, center[2]-edgelength, min);
- vectorInit3d(center[0]+edgelength, center[1]+edgelength, center[2]+edgelength, max);
-
- return triangleIntersectsAABB(p1, p2, p3, min, max);
- }
-
- bool triangleIntersectsBox(vec3_t p1, vec3_t p2, vec3_t p3, vec3_t center, vec3_t edgelengths){
- vec3_t min, max;
-
- vectorInit3d(center[0]-edgelengths[0], center[1]-edgelengths[1], center[2]-edgelengths[2], min);
- vectorInit3d(center[0]+edgelengths[0], center[1]+edgelengths[1], center[2]+edgelengths[2], max);
-
- return triangleIntersectsAABB(p1, p2, p3, min, max);
- }
-
- bool triangleIntersectsAABB(vec3_t p1, vec3_t p2, vec3_t p3, vec3_t min, vec3_t max){
-
- if(p1[0]>max[0] && p2[0]>max[0] && p3[0]>max[0]) // all points right of AABB
- return false;
- if(p1[0]<min[0] && p2[0]<min[0] && p3[0]<min[0]) // all points left of AABB
- return false;
- if(p1[1]>max[1] && p2[1]>max[1] && p3[1]>max[1]) // all points above AABB
- return false;
- if(p1[1]<min[1] && p2[1]<min[1] && p3[1]<min[1]) // all points below AABB
- return false;
- if(p1[2]>max[2] && p2[2]>max[2] && p3[2]>max[2]) // all points in front of AABB
- return false;
- if(p1[2]<min[2] && p2[2]<min[2] && p3[2]<min[2]) // all points behind AABB
- return false;
-
- if(pointIntersectsAABB(p1, min, max) || pointIntersectsAABB(p2, min, max) || pointIntersectsAABB(p3, min, max)) // point in AABB
- return true;
-
- // check edges of triangle against AABB faces
- vec4_t plane;
- float distance;
- vec3_t hitpoint;
-
- // right side
- vectorInit3d(1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(linesegmentIntersectsPlane(p1, p2, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON // THINKABOUTME: geht auch ohne EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p2, p3, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p3, p1, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
-
- // left side
- vectorInit3d(-1.0f, 0.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(linesegmentIntersectsPlane(p1, p2, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p2, p3, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p3, p1, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
-
- // top side
- vectorInit3d(0.0f, 1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(linesegmentIntersectsPlane(p1, p2, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p2, p3, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p3, p1, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
-
- // bottom side
- vectorInit3d(0.0f, -1.0f, 0.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(linesegmentIntersectsPlane(p1, p2, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p2, p3, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p3, p1, plane, &distance, hitpoint)){
- if(hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON
- && hitpoint[2]>min[2]-INTERSECTION_EPSILON && hitpoint[2]<max[2]+INTERSECTION_EPSILON){
- return true;
- }
- }
-
- // front side
- vectorInit3d(0.0f, 0.0f, 1.0f, plane);
- plane[3]=vectorDotP3d(max, plane);
- if(linesegmentIntersectsPlane(p1, p2, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p2, p3, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p3, p1, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON){
- return true;
- }
- }
-
- // back side
- vectorInit3d(0.0f, 0.0f, -1.0f, plane);
- plane[3]=vectorDotP3d(min, plane);
- if(linesegmentIntersectsPlane(p1, p2, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p2, p3, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON){
- return true;
- }
- }
- if(linesegmentIntersectsPlane(p3, p1, plane, &distance, hitpoint)){
- if(hitpoint[1]>min[1]-INTERSECTION_EPSILON && hitpoint[1]<max[1]+INTERSECTION_EPSILON
- && hitpoint[0]>min[0]-INTERSECTION_EPSILON && hitpoint[0]<max[0]+INTERSECTION_EPSILON){
- return true;
- }
- }
-
-
- // check edges of AABB against triangle
- // THINKABOUTME: geht auch schneller
-
- // bottom to top
- vec3_t point1, point2;
- vectorInit3d(min[0], min[1], min[2], point1);
- vectorInit3d(min[0], max[1], min[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- vectorInit3d(max[0], min[1], min[2], point1);
- vectorInit3d(max[0], max[1], min[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- vectorInit3d(max[0], min[1], max[2], point1);
- vectorInit3d(max[0], max[1], max[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- vectorInit3d(min[0], min[1], max[2], point1);
- vectorInit3d(min[0], max[1], max[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- // back to front
- vectorInit3d(min[0], min[1], min[2], point1);
- vectorInit3d(min[0], min[1], max[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- vectorInit3d(min[0], max[1], min[2], point1);
- vectorInit3d(min[0], max[1], max[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- vectorInit3d(max[0], max[1], min[2], point1);
- vectorInit3d(max[0], max[1], max[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- vectorInit3d(max[0], min[1], min[2], point1);
- vectorInit3d(max[0], min[1], max[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- // left to right
- vectorInit3d(min[0], min[1], min[2], point1);
- vectorInit3d(max[0], min[1], min[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- vectorInit3d(min[0], max[1], min[2], point1);
- vectorInit3d(max[0], max[1], min[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- vectorInit3d(min[0], max[1], max[2], point1);
- vectorInit3d(max[0], max[1], max[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- vectorInit3d(min[0], min[1], max[2], point1);
- vectorInit3d(max[0], min[1], max[2], point2);
- if(linesegmentIntersectsTriangle(point1, point2, p1, p2, p3))
- return true;
-
- return false;
- }
-
- bool triangleIntersectsCylinder(vec3_t p1, vec3_t p2, vec3_t p3, vec3_t center, float radius, float height){
- return false;
- }
-
- bool sphereIntersectsSphere(vec3_t center1, float radius1, vec3_t center2, float radius2){
- return vectorPointDistance3d(center1, center2) <= radius1+radius2;
- }
-
- bool cylinderIntersectsCylinder(vec3_t center1, float radius1, float height1, vec3_t center2, float radius2, float height2){
- vec2_t center1_xz, center2_xz;
-
- // check if base caps overlap
- vectorInit2d(center1[0], center1[2], center1_xz);
- vectorInit2d(center2[0], center2[2], center2_xz);
- if(vectorPointDistance2d(center2_xz, center1_xz) > radius1+radius2)
- return false;
-
- // check height intervalls
- if(center1[1]+height1<center2[1] || center2[1]+height2<center1[1])
- return false;
-
- return true;
- }
-
- bool AABBIntersectsAABB(vec3_t min1, vec3_t max1, vec3_t min2, vec3_t max2){
- if(min2[0]>max1[0] || max2[0]<min1[0]) // THINKABOUTME: wegen shorteval alles zusammen??
- return false;
- if(min2[1]>max1[1] || max2[1]<min1[1])
- return false;
- if(min2[2]>max1[2] || max2[2]<min1[2])
- return false;
-
- return true;
- }
-