Help function to know a triangle-box intersection
Blitz3D Forums/Blitz3D Programming/Help function to know a triangle-box intersection
| ||
Hi, I have found a c++ routine to know if a trianle overlapping a box. http://jgt.akpeters.com/papers/AkenineMoller01/tribox.html I need a function in blitz who do the same job, but the function use define blitz don't support define like function. Does exist similar b3d function code who return a boolean result when triangle is in contact with a box ? thanks |
| ||
Wouldn't it be easier to do a line intersect function? |
| ||
Mesh intersect ... Thats the only solution beside doing 3 linepicks (for each side) or doing it really fully mathematical at which point I would recommand creating a userlib from the C++ code for performance reasons. |
| ||
I'd go with Ross. Use line intersects. I use them alot and they are speedy enough. Just don't use them 'everything against everything'. But only if objects are near enough from each other. Problem is if you can have a situation where the box can be completely inside the triangle or vice versa. In that case I would use line intersects along with orientation and point-in-triangle functions. The orientation math calculates if a point C is on the left or right side of A to B. I can provide you the functions if interested. Though I think trying to recode the c++ example to blitz would be more sophisticated. You don't need to have those defines in blitz, just understanding what they do (they don't have to be functions at all). After all, code is just a representation of a solution to a problem. No matter what language it's in. |
| ||
I'm interested by your function Jasu. During your post I have try to convert the link but i have problem with the define function. this is my first step of my translation to bmax code without testing. Function FINDMINMAX(x0:Float, x1:Float, x2:Float, p_fmin:Float var, p_fmax:Float var) p_fmin = x0 p_fmax = x0 If(x1 < p_fmin) Then p_fmin = x1 If(x1 > p_fmax) Then p_fmax = x1 If(x2 < p_fmin) Then p_fmin = x2 If(x2 > p_fmax) Then p_fmax = x2 EndFunction Function planeBoxOverlap:Int(normal:Vector var, d:Float, maxbox:Vector var) Local vmin:Vector = Vector.Create() Local vmax:Vector = Vector.Create() If(normal.x > 0.0) vmin.x = -maxbox.x vmax.x = maxbox.x Else vmin.x = maxbox.x vmax.x = -maxbox.x EndIf If(normal.y > 0.0) vmin.y = -maxbox.y vmax.y = maxbox.y Else vmin.y = maxbox.y vmax.y = -maxbox.y EndIf If(normal.z > 0.0) vmin.z = -maxbox.z vmax.z = maxbox.z Else vmin.z = maxbox.z vmax.z = -maxbox.z EndIf If(normal.DotP(vmin) + d > 0.0) Then Return 0 If(normal.DotP(vmax) + d >= 0.0) Then Return 1 Return 0 EndFunction '======================== X-tests ======================== '#define AXISTEST_X01(a, b, fa, fb) \ ' p0 = a*v0[Y] - b*v0[Z]; \ ' p2 = a*v2[Y] - b*v2[Z]; \ ' if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \ ' rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ ' If(min > rad | | max < - rad) Return 0; Function AXISTEST_X01:Int(a:Float, b:Float, fa:Float, fb:Float, p0:Float, p2:Float, v0:vector, v2:vector, p_fMin:Float, p_fMax:Float, boxhalfsize:Vector) p0 = a * v0.y - b * v0.z p2 = a * v2.y - b * v2.z If(p0 < p2) p_fMin = p0 p_fMax = p2 Else p_fMin = p2 p_fMax = p0 EndIf Local rad:Float = fa * boxhalfsize.y + fb * boxhalfsize.z If(p_fMin > rad Or p_fMax < - rad) Then Return 0 EndFunction '#define AXISTEST_X2(a, b, fa, fb) \ ' p0 = a * v0[Y] - b * v0[Z] ; \ ' p1 = a*v1[Y] - b*v1[Z]; \ ' if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ ' rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ ' if(min>rad || max<-rad) return 0; Function AXISTEST_X2:Int(a:Float, b:Float, fa:Float, fb:Float, p0:Float, p1:Float, v0:vector var, v1:vector var, p_fMin:Float, p_fMax:Float, boxhalfsize:vector var) p0 = a * v0.y - b * v0.z p1 = a * v1.y - b * v1.z If(p0 < p1) p_fMin = p0 p_fMax = p1 Else p_fMin = p1 p_fMax = p0 EndIf Local rad:Float = fa * boxhalfsize.y + fb * boxhalfsize.z If(p_fMin > rad Or p_fMax < - rad) Return 0 EndFunction '======================== Y-tests ======================== '#define AXISTEST_Y02(a, b, fa, fb) \ ' p0 = -a*v0[X] + b*v0[Z]; \ ' p2 = -a*v2[X] + b*v2[Z]; \ ' if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \ ' rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ ' if(min>rad || max<-rad) return 0; Function AXISTEST_Y02:Int(a:Float, b:Float, fa:Float, fb:Float, p0:Float, p2:Float, v0:vector var, v2:vector var, p_fMin:Float, p_fMax:Float, boxhalfsize:vector var) p0 = -a * v0.x + b * v0.z p2 = -a * v2.x + b * v2.z If(p0 < p2) p_fMin = p0 p_fMax = p2 Else p_fMin = p2 p_fMax = p0 EndIf Local rad:Float = fa * boxhalfsize.x + fb * boxhalfsize.z If(p_fMin > rad Or p_fMax < - rad) Return 0 EndFunction '#define AXISTEST_Y1(a, b, fa, fb) \ ' p0 = -a*v0[X] + b*v0[Z]; \ ' p1 = -a*v1[X] + b*v1[Z]; \ ' if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ ' rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ ' if(min>rad || max<-rad) return 0; Function AXISTEST_Y1:Int(a:Float, b:Float, fa:Float, fb:Float, p0:Float, p1:Float, v0:vector var, v1:vector var, p_fMin:Float, p_fMax:Float, boxhalfsize:vector var) p0 = -a * v0.x + b * v0.z p1 = -a * v1.x + b * v1.z If(p0 < p1) p_fMin = p0 p_fMax = p1 Else p_fMin = p1 p_fMax = p0 EndIf Local rad:Float = fa * boxhalfsize.x + fb * boxhalfsize.z If(p_fMin > rad Or p_fMax < - rad) Then Return 0 EndFunction '======================== Z-tests ======================== '#define AXISTEST_Z12(a, b, fa, fb) \ ' p1 = a*v1[X] - b*v1[Y]; \ ' p2 = a*v2[X] - b*v2[Y]; \ ' if(p2<p1) {min=p2; max=p1;} else {min=p1; max=p2;} \ ' rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ ' if(min>rad || max<-rad) return 0; Function AXISTEST_Z12:Int(a:Float, b:Float, fa:Float, fb:Float, p1:Float, p2:Float, v1:vector var, v2:vector var, p_fMin:Float, p_fMax:Float, boxhalfsize:vector var) p1 = a * v1.x - b * v1.y p2 = a * v2.x - b * v2.y If(p2 < p1) p_fMin = p2 p_fMax = p1 Else p_fMin = p1 p_fMax = p2 EndIf Local rad:Float = fa * boxhalfsize.x + fb * boxhalfsize.y If(p_fMin > rad Or p_fMax < - rad) Then Return 0 EndFunction '#define AXISTEST_Z0(a, b, fa, fb) \ ' p0 = a*v0[X] - b*v0[Y]; \ ' p1 = a*v1[X] - b*v1[Y]; \ ' if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ ' rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ ' if(min>rad || max<-rad) return 0; Function AXISTEST_Z0:Int(a:Float, b:Float, fa:Float, fb:Float, p0:Float, p1:Float, v0:vector var, v1:vector var, p_fMin:Float, p_fMax:Float, boxhalfsize:vector var) p0 = a * v0.x - b * v0.y p1 = a * v1.x - b * v1.y If(p0 < p1) p_fMin = p0 p_fMax = p1 Else p_fMin = p1 p_fMax = p0 EndIf local rad:Float = fa * boxhalfsize.x + fb * boxhalfsize.y If(p_fMin > rad Or p_fMax < - rad) Then Return 0 EndFunction Function isTriangleBoxOverlap(p_vBoxcenter:Vector, p_vBoxHalfSize:Vector, p_v0:Vector, p_v1:Vector, p_v2:Vector) ' use separating axis theorem To test overlap between triangle And box ' need to test for overlap in these directions: ' 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle ' we do not even need to test these) ' 2) normal of the triangle ' 3) crossproduct(edge from tri, {x,y,z}-directin) ' this gives 3x3=9 more tests Local l_v0:Vector = Vector.Create() Local l_v1:Vector = Vector.Create() Local l_v2:Vector = Vector.Create() Local l_fMin:Float Local l_fMax:Float Local d:Float Local p0:Float Local p1:Float Local p2:Float Local fex:Float Local fey:Float Local fez:Float Local normal:Vector = Vector.Create() Local e0:Vector = Vector.Create() Local e1:Vector = Vector.Create() Local e2:Vector = Vector.Create() ' This is the fastest branch on Sun ' move everything so that the boxcenter is in (0,0,0) l_v0 = p_v0.Sub(p_vboxcenter) l_v1 = p_v1.Sub(p_vboxcenter) l_v2 = p_v2.Sub(p_vboxcenter) 'compute triangle edges e0 = l_v1.sub(l_v0) ' tri edge 0 e1 = l_v2.sub(l_v1) ' tri edge 1 e2 = l_v0.sub(l_v2) 'tri edge 2 ' Bullet 3: ' ' test the 9 tests first (this was faster) fex = Abs(e0.x) fey = Abs(e0.y) fez = Abs(e0.z) AXISTEST_X01(e0.z, e0.y, fez, fey, p0, p2, l_v0, l_v2, l_fMin, l_fMax, p_vBoxHalfSize) AXISTEST_Y02(e0.z, e0.x, fez, fex, p0, p2, l_v0, l_v2, l_fMin, l_fMax, p_vBoxHalfSize) AXISTEST_Z12(e0.y, e0.x, fey, fex, p1, p2, l_v1, l_v2, l_fMin, l_fMax, p_vBoxHalfSize) fex = Abs(e1.x) fey = Abs(e1.y) fez = Abs(e1.z) AXISTEST_X01(e1.z, e1.y, fez, fey, p0, p2, l_v0, l_v2, l_fMin, l_fMax, p_vBoxHalfSize) AXISTEST_Y02(e1.z, e1.x, fez, fex, p0, p2, l_v0, l_v2, l_fMin, l_fMax, p_vBoxHalfSize) AXISTEST_Z0(e1.y, e1.X, fey, fex, p0, p1, l_v0, l_v1, l_fMin, l_fMax, p_vBoxHalfSize) fex = Abs(e2.X) fey = Abs(e2.Y) fez = Abs(e2.Z) AXISTEST_X2(e2.z, e2.y, fez, fey, p0, p1, l_v0, l_v1, l_fMin, l_fMax, p_vBoxHalfSize) AXISTEST_Y1(e2.z, e2.x, fez, fex, p0, p1, l_v0, l_v1, l_fMin, l_fMax, p_vBoxHalfSize) AXISTEST_Z12(e2.y, e2.x, fey, fex, p1, p2, l_v1, l_v2, l_fMin, l_fMax, p_vBoxHalfSize) ' Bullet 1: ' first test overlap in the {x,y,z}-directions ' find min, max of the triangle each direction, and test for overlap in ' that direction -- this is equivalent to testing a minimal AABB around ' the triangle against the AABB ' test in X-direction FINDMINMAX(l_v0.x, l_v1.X, l_v2.X, l_fMin, l_fMax) ; If(l_fMin > p_vBoxhalfsize.x Or l_fMax < - p_vBoxhalfsize.x) Then Return 0 ' test in Y-direction FINDMINMAX(l_v0.y, l_v1.y, l_v2.y, l_fMin, l_fMax) ; If(l_fMin > p_vBoxhalfsize.y Or l_fMax < - p_vBoxhalfsize.y) Then Return 0 ' test in Z-direction FINDMINMAX(l_v0.z, l_v1.z, l_v2.z, l_fMin, l_fMax) ; If(l_fMin > p_vBoxhalfsize.z Or l_fMax < - p_vBoxhalfsize.z) Then Return 0 ' Bullet 2: ' test if the box intersects the plane of the triangle ' compute plane equation of triangle: normal*x+d=0 normal = e0.CrossP(e1) d = -normal.DotP(l_v0) ' plane eq: normal.x+d=0 If(planeBoxOverlap(normal, d, p_vBoxhalfsize) = False) Then Return 0 Return 1 ' box and triangle overlaps End Function here the vector class http://www.blitzmax.com/codearcs/codearcs.php?code=1550 |
| ||
Jasu, figuring out if the shape lines with the box should be easy. If all three intersects fail, take any point of the triangle and see if it lies within the bounds of the box. I assume we are talking about 2d shapes here btw :o) |
| ||
I have merge all functions into a class TriOverlapBox How to use TriOverlapBox. Easy. Define the box position and size and your 3 vertices triangle using vector definition. Like this: CenterOfBox:Vector = Vector.Create(0, 0, 0) BoxHalfSize:Vector = Vector.Create(50, 50, 50) TriangleVertex1:Vector = Vector.Create(100, 0, 0) TriangleVertex2:Vector = Vector.Create(- 100, 0, 0) TriangleVertex3:Vector = Vector.Create(0, 100, 0) ' Put your vector as parameters TriOverlapBox.isTriangleBoxOverlap(CenterOfBox, BoxHalfSize, TriangleVertex1, TriangleVertex2, TriangleVertex3) the function "isTriangleBoxOverlap" return 1 when Triangle overlap your box. Else return 0 All the code is merged into class TriOverlapBox Type TriOverlapBox ' Date 2007/Jan/06 ' ' Class Who test triangle-box intersection ' Code converted by Patmaba from C code to Bmax code ' http://jgt.akpeters.com/papers/AkenineMoller01/tribox.html ' ' Thanks to Alexx and all members of Blitz3d who help me ' ' Sample how to use 'CenterOfBox:Vector = Vector.Create(0, 0, 0) 'BoxHalfSize:Vector = Vector.Create(50, 50, 50) 'TriangleVertex1:Vector = Vector.Create(100, 0, 0) 'TriangleVertex2:Vector = Vector.Create(- 100, 0, 0) 'TriangleVertex3:Vector = Vector.Create(0, 100, 0) ' Put your vector as parameters 'TriOverlapBox.isTriangleBoxOverlap(CenterOfBox, BoxHalfSize, TriangleVertex1, TriangleVertex2, TriangleVertex3) Global g_v0:Vector = Vector.Create() Global g_v1:Vector = Vector.Create() Global g_v2:Vector = Vector.Create() Global boxhalfsize:Vector = Vector.Create() Global p0:Float Global p1:Float Global p2:Float Global g_fMin:Float Global g_fMax:Float Function FINDMINMAX(x0:Float, x1:Float, x2:Float, p_fmin:Float var, p_fmax:Float var) p_fmin = x0 p_fmax = x0 If(x1 < p_fmin) Then p_fmin = x1 If(x1 > p_fmax) Then p_fmax = x1 If(x2 < p_fmin) Then p_fmin = x2 If(x2 > p_fmax) Then p_fmax = x2 EndFunction Function planeBoxOverlap:Int(normal:Vector var, d:Float, maxbox:Vector var) Local vmin:Vector = Vector.Create() Local vmax:Vector = Vector.Create() If(normal.x > 0.0) vmin.x = -maxbox.x vmax.x = maxbox.x Else vmin.x = maxbox.x vmax.x = -maxbox.x EndIf If(normal.y > 0.0) vmin.y = -maxbox.y vmax.y = maxbox.y Else vmin.y = maxbox.y vmax.y = -maxbox.y EndIf If(normal.z > 0.0) vmin.z = -maxbox.z vmax.z = maxbox.z Else vmin.z = maxbox.z vmax.z = -maxbox.z EndIf If(normal.DotP(vmin) + d > 0.0) Then Return 0 If(normal.DotP(vmax) + d >= 0.0) Then Return 1 Return 0 EndFunction '======================== X-tests ======================== '#define AXISTEST_X01(a, b, fa, fb) \ ' p0 = a*v0[Y] - b*v0[Z]; \ ' p2 = a*v2[Y] - b*v2[Z]; \ ' if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \ ' rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ ' If(min > rad | | max < - rad) Return 0; Function AXISTEST_X01:Int(a:Float, b:Float, fa:Float, fb:Float) p0 = a * g_v0.y - b * g_v0.z p2 = a * g_v2.y - b * g_v2.z If(p0 < p2) g_fMin = p0 g_fMax = p2 Else g_fMin = p2 g_fMax = p0 EndIf Local rad:Float = fa * boxhalfsize.y + fb * boxhalfsize.z If (g_fMin > rad Or g_fMax < - rad) Then Return 0 Else Return 1 End If EndFunction '#define AXISTEST_X2(a, b, fa, fb) \ ' p0 = a * v0[Y] - b * v0[Z] ; \ ' p1 = a*v1[Y] - b*v1[Z]; \ ' if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ ' rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ ' if(min>rad || max<-rad) return 0; Function AXISTEST_X2:Int(a:Float, b:Float, fa:Float, fb:Float) p0 = a * g_v0.y - b * g_v0.z p1 = a * g_v1.y - b * g_v1.z If(p0 < p1) g_fMin = p0 g_fMax = p1 Else g_fMin = p1 g_fMax = p0 EndIf Local rad:Float = fa * boxhalfsize.y + fb * boxhalfsize.z If (g_fMin > rad Or g_fMax < - rad) Then Return 0 Else Return 1 End If EndFunction '======================== Y-tests ======================== '#define AXISTEST_Y02(a, b, fa, fb) \ ' p0 = -a*v0[X] + b*v0[Z]; \ ' p2 = -a*v2[X] + b*v2[Z]; \ ' if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \ ' rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ ' if(min>rad || max<-rad) return 0; Function AXISTEST_Y02:Int(a:Float, b:Float, fa:Float, fb:Float) p0 = -a * g_v0.x + b * g_v0.z p2 = -a * g_v2.x + b * g_v2.z If(p0 < p2) g_fMin = p0 g_fMax = p2 Else g_fMin = p2 g_fMax = p0 EndIf Local rad:Float = fa * boxhalfsize.x + fb * boxhalfsize.z If (g_fMin > rad Or g_fMax < - rad) Then Return 0 Else Return 1 End If EndFunction '#define AXISTEST_Y1(a, b, fa, fb) \ ' p0 = -a*v0[X] + b*v0[Z]; \ ' p1 = -a*v1[X] + b*v1[Z]; \ ' if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ ' rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ ' if(min>rad || max<-rad) return 0; Function AXISTEST_Y1:Int(a:Float, b:Float, fa:Float, fb:Float) p0 = -a * g_v0.x + b * g_v0.z p1 = -a * g_v1.x + b * g_v1.z If(p0 < p1) g_fMin = p0 g_fMax = p1 Else g_fMin = p1 g_fMax = p0 EndIf Local rad:Float = fa * boxhalfsize.x + fb * boxhalfsize.z If (g_fMin > rad Or g_fMax < - rad) Then Return 0 Else Return 1 End If EndFunction '======================== Z-tests ======================== '#define AXISTEST_Z12(a, b, fa, fb) \ ' p1 = a*v1[X] - b*v1[Y]; \ ' p2 = a*v2[X] - b*v2[Y]; \ ' if(p2<p1) {min=p2; max=p1;} else {min=p1; max=p2;} \ ' rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ ' if(min>rad || max<-rad) return 0; Function AXISTEST_Z12:Int(a:Float, b:Float, fa:Float, fb:Float) p1 = a * g_v1.x - b * g_v1.y p2 = a * g_v2.x - b * g_v2.y If(p2 < p1) g_fMin = p2 g_fMax = p1 Else g_fMin = p1 g_fMax = p2 EndIf Local rad:Float = fa * boxhalfsize.x + fb * boxhalfsize.y If (g_fMin > rad Or g_fMax < - rad) Then Return 0 Else Return 1 End If EndFunction '#define AXISTEST_Z0(a, b, fa, fb) \ ' p0 = a*v0[X] - b*v0[Y]; \ ' p1 = a*v1[X] - b*v1[Y]; \ ' if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ ' rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ ' if(min>rad || max<-rad) return 0; Function AXISTEST_Z0:Int(a:Float, b:Float, fa:Float, fb:Float) p0 = a * g_v0.x - b * g_v0.y p1 = a * g_v1.x - b * g_v1.y If(p0 < p1) g_fMin = p0 g_fMax = p1 Else g_fMin = p1 g_fMax = p0 EndIf Local rad:Float = fa * boxhalfsize.x + fb * boxhalfsize.y If (g_fMin > rad Or g_fMax < - rad) Then Return 0 Else Return 1 End If EndFunction Function isTriangleBoxOverlap(p_vBoxcenter:Vector, p_vBoxHalfSize:Vector, p_triverts0:Vector, p_triverts1:Vector, p_triverts2:Vector) ' use separating axis theorem To test overlap between triangle And box ' need to test for overlap in these directions: ' 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle ' we do not even need to test these) ' 2) normal of the triangle ' 3) crossproduct(edge from tri, {x,y,z}-directin) ' this gives 3x3=9 more tests Local d:Float Local fex:Float Local fey:Float Local fez:Float Local normal:Vector = Vector.Create() Local e0:Vector = Vector.Create() Local e1:Vector = Vector.Create() Local e2:Vector = Vector.Create() InitGlobalsVariables() ' This is the fastest branch on Sun * / ' move everything so that the boxcenter is in (0,0,0) */ 'SUB(v0,triverts[0],boxcenter); 'SUB(v1,triverts[1],boxcenter); 'SUB(v2,triverts[2],boxcenter); g_v0 = p_triverts0.Sub(p_vboxcenter) g_v1 = p_triverts1.Sub(p_vboxcenter) g_v2 = p_triverts2.Sub(p_vboxcenter) ' compute triangle edges */ 'SUB(e0,v1,v0); /* tri edge 0 */ 'SUB(e1,v2,v1); /* tri edge 1 */ 'SUB(e2,v0,v2); /* tri edge 2 */ ' This is the fastest branch on Sun ' move everything so that the boxcenter is in (0,0,0) 'compute triangle edges e0 = g_v1.sub(g_v0) ' tri edge 0 e1 = g_v2.sub(g_v1) ' tri edge 1 e2 = g_v0.sub(g_v2) 'tri edge 2 ' Bullet 3: ' ' test the 9 tests first (this was faster) ' fex = fabs(e0[X] ) ; ' fey = fabs(e0[Y]); ' fez = fabs(e0[Z]); ' AXISTEST_X01(e0[Z], e0[Y], fez, fey); ' AXISTEST_Y02(e0[Z], e0[X], fez, fex); ' AXISTEST_Z12(e0[Y], e0[X], fey, fex); fex = Abs(e0.x) fey = Abs(e0.y) fez = Abs(e0.z) If AXISTEST_X01(e0.z, e0.y, fez, fey) = 0 Then Return 0 If AXISTEST_Y02(e0.z, e0.x, fez, fex) = 0 Then Return 0 If AXISTEST_Z12(e0.y, e0.x, fey, fex) = 0 Then Return 0 fex = Abs(e1.x) fey = Abs(e1.y) fez = Abs(e1.z) If AXISTEST_X01(e1.z, e1.y, fez, fey) = 0 Then Return 0 If AXISTEST_Y02(e1.z, e1.x, fez, fex) = 0 Then Return 0 If AXISTEST_Z0(e1.y, e1.X, fey, fex) = 0 Then Return 0 fex = Abs(e2.X) fey = Abs(e2.Y) fez = Abs(e2.Z) If AXISTEST_X2(e2.z, e2.y, fez, fey) = 0 Then Return 0 If AXISTEST_Y1(e2.z, e2.x, fez, fex) = 0 Then Return 0 If AXISTEST_Z12(e2.y, e2.x, fey, fex) = 0 Then Return 0 ' Bullet 1: ' first test overlap in the {x,y,z}-directions ' find min, max of the triangle each direction, and test for overlap in ' that direction -- this is equivalent to testing a minimal AABB around ' the triangle against the AABB ' test in X-direction FINDMINMAX(g_v0.x, g_v1.X, g_v2.X, g_fMin, g_fMax) If(g_fMin > p_vBoxhalfsize.x Or g_fMax < - p_vBoxhalfsize.x) Then Return 0 ' test in Y-direction FINDMINMAX(g_v0.y, g_v1.y, g_v2.y, g_fMin, g_fMax) If(g_fMin > p_vBoxhalfsize.y Or g_fMax < - p_vBoxhalfsize.y) Then Return 0 ' test in Z-direction FINDMINMAX(g_v0.z, g_v1.z, g_v2.z, g_fMin, g_fMax) ; If(g_fMin > p_vBoxhalfsize.z Or g_fMax < - p_vBoxhalfsize.z) Then Return 0 ' Bullet 2: ' test if the box intersects the plane of the triangle ' compute plane equation of triangle: normal*x+d=0 normal = e0.CrossP(e1) d = -normal.DotP(g_v0) ' plane eq: normal.x+d=0 If(planeBoxOverlap(normal, d, p_vBoxhalfsize) = False) Then Return 0 Return 1 ' box and triangle overlaps End Function Function InitGlobalsVariables() g_v0:Vector = Vector.Create() g_v1:Vector = Vector.Create() g_v2:Vector = Vector.Create() boxhalfsize:Vector = Vector.Create() p0 = 0.0 p1 = 0.0 p2 = 0.0 g_fMin = 0.0 g_fMax = 0.0 End Function End Type Post any comment if you encounter error, please |
| ||
I added my functions to the code archives. http://www.blitzbasic.com/codearcs/codearcs.php?code=2180 For determening if a point is in a triangle, use to one by Rob Farley that was already there. That's what I'm using. http://www.blitzbasic.com/codearcs/codearcs.php?code=1992 |