2 Commits 81a45094c1 ... d84a5a3656

Author SHA1 Message Date
  izzy d84a5a3656 box/ray clipping, fixed plane/ray intersect fn 1 week ago
  izzy c00540838c 2d triangle point and line functions 2 weeks ago
5 changed files with 111 additions and 37 deletions
  1. 1 0
      c3dlas.c
  2. 4 0
      c3dlas.h
  3. 61 36
      intersect/box.c
  4. 1 1
      intersect/plane.c
  5. 44 0
      intersect/triangle.c

+ 1 - 0
c3dlas.c

@@ -2701,6 +2701,7 @@ Vector3 evalCubicHermite3D(float t, Vector3 p0, Vector3 p1, Vector3 m0, Vector3
 #include "intersect/plane.c"
 #include "intersect/box.c"
 #include "intersect/line.c"
+#include "intersect/triangle.c"
 
 
 

+ 4 - 0
c3dlas.h

@@ -651,6 +651,8 @@ Vector3 vS2C3(Vector3 s);
 float vDistPointLine2(Vector2 p, Line2 ls);
 float vDistPointLine3(Vector3 p, Line3 ls);
 
+float distPoint2Triangle2(Vector2 a, Vector2 tri[3]);
+
 // Also returns the normalized distance along the line to the closest point
 float vDistTPointLine2(Vector2 p, Line2 ls, float* T);
 float vDistTPointLine3(Vector3 p, Line3 ls, float* T);
@@ -665,6 +667,8 @@ Line3 shortestLineFromLineToLine(Line3* a, Line3* b); // same algorithm as the a
 // Quad *must* be a rectangle, and the vertices must be ordered in a loop
 float distLine2Rect2(Line2 a, Quad2 q);
 
+float distLine2Triangle2(Line2 a, Vector2 tri[3]);
+
 float distTPointRay3(Vector3 p, Ray3 r, float* T);
 float dist2TPointRay3(Vector3 p, Ray3 r, float* T);
 

+ 61 - 36
intersect/box.c

@@ -149,47 +149,72 @@ bool boxContainsPoint3(AABB3 b, Vector3 p) {
 
 int boxClipRay(AABB3* b, Ray3 r, Line3* out) {
 	
-	// intercept distances
-	f32 tx_1 = (b->min.x - r.o.x) / r.d.x;
-	f32 ty_1 = (b->min.y - r.o.y) / r.d.y;
-	f32 tz_1 = (b->min.z - r.o.z) / r.d.z;
-	f32 tx_2 = (b->max.x - r.o.x) / r.d.x;
-	f32 ty_2 = (b->max.y - r.o.y) / r.d.y;
-	f32 tz_2 = (b->max.z - r.o.z) / r.d.z;
-	
-	f32 tx_min = MIN(tx_1, tx_2); 
-	f32 ty_min = MIN(ty_1, ty_2); 
-	f32 tz_min = MIN(tz_1, tz_2); 
-	f32 tx_max = MIN(tx_1, tx_2); 
-	f32 ty_max = MIN(ty_1, ty_2); 
-	f32 tz_max = MIN(tz_1, tz_2); 
-	
-	// ALL HORRIBLY WRONG
-	
-	f32 min_t = -FLT_MAX;
-	
-	// check if the ray intersects on various axes
-	if(tx_min < ty_max && tx_min < tz_max) {
-		min_t = tx_min;
-	}
+	vec3 norms[] = {
+		{-1,0,0},
+		{0,-1,0},
+		{0,0,-1},
+		{1,0,0},
+		{0,1,0},
+		{0,0,1},
+	};
+	
+	f32 ds[] = {
+		b->max.x,
+		b->max.y,
+		b->max.z,
+		b->min.x,
+		b->min.y,
+		b->min.z,
+	}; 
+	
+	f32 mint = -FLT_MAX;
+	f32 maxt = -FLT_MAX;
 	
-	if(ty_min < tx_max && ty_min < tz_max) {
-//		if(
+	for(int i = 0; i < 6; i++) {
+	
+		float d = vDot3(norms[i], r.d);
+	
+		if(fabs(d) < FLT_CMP_EPSILON) continue; // parallel
+		
+		float t = (vDot3(norms[i], r.o) + ds[i]) / -d; 
+		
+		vec3 pt = vAdd3(r.o, vScale3(r.d, t));
+		
+		switch(i) { // clamp to the 
+			case 0:
+			case 3:
+				if(pt.y > b->max.y || pt.y < b->min.y) continue;
+				if(pt.z > b->max.z || pt.z < b->min.z) continue;
+				break;
+				
+			case 1:
+			case 4:
+				if(pt.x > b->max.x || pt.x < b->min.x) continue;
+				if(pt.z > b->max.z || pt.z < b->min.z) continue;
+				break;
+				
+			case 2:
+			case 5:
+				if(pt.x > b->max.x || pt.x < b->min.x) continue;
+				if(pt.y > b->max.y || pt.y < b->min.y) continue;
+				break;
+		}
+		
+		mint = fminf(mint, t);
+		maxt = fmaxf(maxt, t);
 	}
-//		&& (tz_min < tx_max && tz_min < ty_max)
-//	) {
-//		return C3DLAS_DISJOINT;
-//	}
 	
-//	f32 entry = MAX(tx_min, ty_min, tz_min);
-//	f32 exit = MIN(tx_max, ty_max, tz_max);
+	mint = fmaxf(0, mint); // clamp to ray origin
 	
-//	if(out) {
-//		out->start = vAdd(r.o, vScale(r.d, entry));
-//		out->end = vAdd(r.o, vScale(r.d, exit));
-//	}
+	if(maxt != FLT_MAX) {
+		out->a = vAdd3(r.o, vScale3(r.d, mint));
+		out->b = vAdd3(r.o, vScale3(r.d, maxt));
 	
-	return C3DLAS_INTERSECT;
+		return C3DLAS_INTERSECT;
+	}
+	else {
+		return C3DLAS_DISJOINT;
+	}
 }
 
 

+ 1 - 1
intersect/plane.c

@@ -99,7 +99,7 @@ int intersectPlaneRay3p(Plane* p, Ray3* r, Vector3* ipoint, float* idist) {
 	
 	if(fabs(d) < FLT_CMP_EPSILON) return C3DLAS_PARALLEL; // TODO: check for coplanarity?
 	
-	float t = 1.0 - (vDot3(p->n, r->o) + d) / vDot3(p->n, r->d); 
+	float t = -(vDot3(p->n, r->o) + p->d) / d; 
 		
 	*ipoint = vAdd3(r->o, vScale3(r->d, t));
 	*idist = t;

+ 44 - 0
intersect/triangle.c

@@ -0,0 +1,44 @@
+
+
+
+
+float distLine2Triangle2(Line2 a, Vector2 tri[3]) {
+	
+	// check the lines around the outside
+	float d[3];
+	
+	for(int i = 0; i < 3; i++) {
+		d[i] = distLine2Line2(a, (Line2){tri[i], tri[(i + 1) % 3]});
+		if(d[i] == 0) return 0;
+	}
+	
+	// check if the line is entirely inside the triangle,
+	//   if one point (and therefore both points) is inside 
+	
+	if(triPointInside2p(&a.start, tri, tri + 1, tri + 2)) {
+		return 0;
+	}
+	
+	// the line is outside; one of the corners is closest, find which one
+	return MIN(MIN(d[0], d[1]), d[2]);
+}
+
+float distPoint2Triangle2(Vector2 a, Vector2 tri[3]) {
+	
+	// check if the point is inside the triangle,
+	if(triPointInside2p(&a, tri, tri + 1, tri + 2)) {
+		return 0;
+	}
+	
+	// check the lines around the outside
+	float d[3];
+	
+	for(int i = 0; i < 3; i++) {
+		d[i] = vDistPointLine2(a, (Line2){tri[i], tri[(i + 1) % 3]});
+		if(d[i] == 0) return 0;
+	}
+	
+	// the point is outside; one of the corners is closest, find which one
+	return MIN(MIN(d[0], d[1]), d[2]);
+}
+