Raycast
Posted: Sun Mar 08, 2009 4:55 pm

For those that don't want to wait for BeRo's physics implementation .. a basic Raycast ( Ray VS Triangle ) Library. Use in combination with the Matrix Library when dealing with rotated objects.
*Since ZGE rounds off values with more then 3 decimals, 0.001 is the lowest Epsilon you can use .. ( otherwise you'd want to go with something like 0.00001 ).
*Returns the collision state / bool, so you have to pull out the variables to calculate the intersection point / normal yourself.
Code: Select all
void Sub(int K,
float X1, float Y1, float Z1,
float X2, float Y2, float Z2)
{
Vector[K,0] = X1-X2;
Vector[K,1] = Y1-Y2;
Vector[K,2] = Z1-Z2;
}
//
void Cross(int K,
float X1, float Y1, float Z1,
float X2, float Y2, float Z2)
{
Vector[K,0] = Y1*Z2-Z1*Y2;
Vector[K,1] = Z1*X2-X1*Z2;
Vector[K,2] = X1*Y2-Y1*X2;
}
//
float Dot(float X1, float Y1, float Z1,
float X2, float Y2, float Z2)
{
return X1*X2+Y1*Y2+Z1*Z2;
}
//
int RayTriangle(float OX, float OY, float OZ,
float DX, float DY, float DZ,
float X1, float Y1, float Z1,
float X2, float Y2, float Z2,
float X3, float Y3, float Z3)
{
float R, S, T, U, V;
Sub(1,X2,Y2,Z2,X1,Y1,Z1);
Sub(2,X3,Y3,Z3,X1,Y1,Z1);
Cross(3,DX,DY,DZ,Vector[2,0],Vector[2,1],Vector[2,2]);
R = Dot(Vector[1,0],Vector[1,1],Vector[1,2],Vector[3,0],Vector[3,1],Vector[3,2]);
Sub(4,OX,OY,OZ,X1,Y1,Z1);
S = 1/R;
Cross(5,Vector[4,0],Vector[4,1],Vector[4,2],Vector[1,0],Vector[1,1],Vector[1,2]);
if(R <= Epsilon && R >= Epsilon*-1)
{
return 0;
}
else
{
if(R > Epsilon)
{
Debug = U;
U = Dot(Vector[4,0],Vector[4,1],Vector[4,2],Vector[3,0],Vector[3,1],Vector[3,2]);
if(U < 0 || U > R)
{
return 0;
}
V = Dot(DX,DY,DZ,Vector[5,0],Vector[5,1],Vector[5,2]);
if(V < 0 || U+V > R)
{
return 0;
}
}
if(R < Epsilon*-1)
{
U = Dot(Vector[4,0],Vector[4,1],Vector[4,2],Vector[3,0],Vector[3,1],Vector[3,2]);
if(U > 0 || U < R)
{
return 0;
}
V = Dot(DX,DY,DZ,Vector[5,0],Vector[5,1],Vector[5,2]);
if(V > 0 || U+V < R)
{
return 0;
}
}
}
T = Dot(Vector[2,0],Vector[2,1],Vector[2,2],Vector[5,0],Vector[5,1],Vector[5,2]);
U *= S;
V *= S;
return 1;
}
K