Jump to content
• Advertisement

# Ray vs Box Issue

This topic is 1331 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

## Recommended Posts

Sup Everyone,

I'm having a problem where my Ray vs Box algorithm doesn't seem to work.

Sometimes it return a collision, but 98% of the time it doesn't.

The algorithm seems good though.

Can anyone tell me if you see anything misplaced or missing?

This is a code snippet from my Wall3x3 Object.

m_x, m_y, m_z is the center of my wall.

x,y,z are the coordinates of the Origin of the Ray.

Roty and Rotx are the angles of the Ray's direction.

m_Cx, m_Cy and m_Cz are the coordinates of the collision point.

Finally, my wall is 600 wide by 20 thick by 600 high. Thus the m_x - 300 and m_x + 300 and ect and my Box boundaries.

bool CWall3x3::FastProjectileCollisions( GLfloat x, GLfloat y, GLfloat z, GLfloat Rotx, GLfloat Roty )
{

//COMPUTE Ts
GLfloat T0x = (m_x - 300.0f - x)/( -(float)sin(Roty*piover180) );
GLfloat T1x = (m_x + 300.0f - x)/( -(float)sin(Roty*piover180) );

GLfloat T0y = (m_y - 300.0f - y)/( -(float)sin(Rotx*piover180) );
GLfloat T1y = (m_y + 300.0f - y)/( -(float)sin(Rotx*piover180) );

GLfloat T0z = (m_z + 10.0f - z)/( -(float)cos(Roty*piover180) );
GLfloat T1z = (m_z - 10.0f - z)/( -(float)cos(Roty*piover180) );

//COMPUTE TMIN AND TMAX
GLfloat Tmin;
GLfloat Tmax;

//Tmin
if(T0x > T0y)
Tmin = T0x;

if(T0y > T0x)
Tmin = T0y;

//Tmax
if(T1x > T1y)
Tmax = T1x;

if(T1y > T1x)
Tmax = T1y;

//FIRST MISS BOX CHECK
if(T0x > T1y || T0y > T1x)
return false;

//EXTEND TO 3D
//SECOND MISS BOX CHECK
if(Tmin > T1z || T0z > Tmax)
return false;

//ALSO
if(T0z > Tmin)
Tmin = T0z;

if(T1z < Tmax)
Tmax = T1z;

//COMPUTE COLLISION COORDINATES
m_Cx = x - (float)sin(Roty*piover180) * Tmin;
m_Cy = y - (float)sin(Rotx*piover180) * Tmin;
m_Cz = z - (float)cos(Roty*piover180) * Tmin;

//RAY INTERSECTS RETURN TRUE
return true;

}
Edited by Cydriic

#### Share this post

##### Share on other sites
Advertisement
I highly suggest you set up a simple test case with a ray that is known to collide (but doesn't work with your code) and step through your logic in a debugger.

#### Share this post

##### Share on other sites

Thank Apoch,

I followed your advice and went to work! Fixed it, now it works awesome here is the code.

So basically I compute all my potential intersection point Ts.

Then I test the potential itersection points on the Box collision mesh, discarding all point related to a negative T, because that would mean my Ray is colliding with a Box that is behind the character firing.

So here is the fixed code for my Ray Vs Box, thanks everyone.

Note that the collision test is different depending on the Rotation of the Box around the Y (up vector) Axis. Because, this code applies for Boxes that are Aligned with the Grid (where Y is the Up vector). Therefore, my box will only have two possible Rotations in the world 0.0f and 90.0f.

I use it for outside containers, crates, tables and walls in my game. Other objects use a Ray vs Sphere Collision test for now.

bool CWall3x3::FastProjectileCollisions( GLfloat x, GLfloat y, GLfloat z, GLfloat Rotx, GLfloat Roty )
{

if(m_Roty == 0.0f)
{

//COMPUTE Ts
GLfloat T0x = (m_x - 300.0f - x)/( -(float)sin(Roty*piover180) );
GLfloat T1x = (m_x + 300.0f - x)/( -(float)sin(Roty*piover180) );

GLfloat T0y = (m_y - 300.0f - y)/( -(float)sin(Rotx*piover180) );
GLfloat T1y = (m_y + 300.0f - y)/( -(float)sin(Rotx*piover180) );

GLfloat T0z = (m_z - 10.0f - z)/( -(float)cos(Roty*piover180) );
GLfloat T1z = (m_z + 10.0f - z)/( -(float)cos(Roty*piover180) );

//COMPUTE COLLISION COORDINATES

if(T0x > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T0x;
m_Cy = y - (float)sin(Rotx*piover180) * T0x;
m_Cz = z - (float)cos(Roty*piover180) * T0x;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 300.0f && m_Cx <= m_x + 300.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 10.0f && m_Cz <= m_z + 10.0f)
return true;
}

if(T1x > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T1x;
m_Cy = y - (float)sin(Rotx*piover180) * T1x;
m_Cz = z - (float)cos(Roty*piover180) * T1x;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 300.0f && m_Cx <= m_x + 300.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 10.0f && m_Cz <= m_z + 10.0f)
return true;
}

if(T0y > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T0y;
m_Cy = y - (float)sin(Rotx*piover180) * T0y;
m_Cz = z - (float)cos(Roty*piover180) * T0y;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 300.0f && m_Cx <= m_x + 300.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 10.0f && m_Cz <= m_z + 10.0f)
return true;
}

if(T1y > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T1y;
m_Cy = y - (float)sin(Rotx*piover180) * T1y;
m_Cz = z - (float)cos(Roty*piover180) * T1y;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 300.0f && m_Cx <= m_x + 300.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 10.0f && m_Cz <= m_z + 10.0f)
return true;
}

if(T0z > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T0z;
m_Cy = y - (float)sin(Rotx*piover180) * T0z;
m_Cz = z - (float)cos(Roty*piover180) * T0z;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 300.0f && m_Cx <= m_x + 300.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 10.0f && m_Cz <= m_z + 10.0f)
return true;
}

if(T1z > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T1z;
m_Cy = y - (float)sin(Rotx*piover180) * T1z;
m_Cz = z - (float)cos(Roty*piover180) * T1z;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 300.0f && m_Cx <= m_x + 300.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 10.0f && m_Cz <= m_z + 10.0f)
return true;
}

}

if(m_Roty == 90.0f)
{

//COMPUTE Ts
GLfloat T0x = (m_x - 10.0f - x)/( -(float)sin(Roty*piover180) );
GLfloat T1x = (m_x + 10.0f - x)/( -(float)sin(Roty*piover180) );

GLfloat T0y = (m_y - 300.0f - y)/( -(float)sin(Rotx*piover180) );
GLfloat T1y = (m_y + 300.0f - y)/( -(float)sin(Rotx*piover180) );

GLfloat T0z = (m_z - 300.0f - z)/( -(float)cos(Roty*piover180) );
GLfloat T1z = (m_z + 300.0f - z)/( -(float)cos(Roty*piover180) );

//COMPUTE COLLISION COORDINATES

if(T0x > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T0x;
m_Cy = y - (float)sin(Rotx*piover180) * T0x;
m_Cz = z - (float)cos(Roty*piover180) * T0x;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 10.0f && m_Cx <= m_x + 10.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 300.0f && m_Cz <= m_z + 300.0f)
return true;
}

if(T1x > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T1x;
m_Cy = y - (float)sin(Rotx*piover180) * T1x;
m_Cz = z - (float)cos(Roty*piover180) * T1x;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 10.0f && m_Cx <= m_x + 10.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 300.0f && m_Cz <= m_z + 300.0f)
return true;
}

if(T0y > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T0y;
m_Cy = y - (float)sin(Rotx*piover180) * T0y;
m_Cz = z - (float)cos(Roty*piover180) * T0y;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 10.0f && m_Cx <= m_x + 10.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 300.0f && m_Cz <= m_z + 300.0f)
return true;
}

if(T1y > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T1y;
m_Cy = y - (float)sin(Rotx*piover180) * T1y;
m_Cz = z - (float)cos(Roty*piover180) * T1y;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 10.0f && m_Cx <= m_x + 10.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 300.0f && m_Cz <= m_z + 300.0f)
return true;
}

if(T0z > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T0z;
m_Cy = y - (float)sin(Rotx*piover180) * T0z;
m_Cz = z - (float)cos(Roty*piover180) * T0z;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 10.0f && m_Cx <= m_x + 10.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 300.0f && m_Cz <= m_z + 300.0f)
return true;
}

if(T1z > 0)
{
m_Cx = x - (float)sin(Roty*piover180) * T1z;
m_Cy = y - (float)sin(Rotx*piover180) * T1z;
m_Cz = z - (float)cos(Roty*piover180) * T1z;

//RAY INTERSECTS RETURN TRUE
if(m_Cx >= m_x - 10.0f && m_Cx <= m_x + 10.0f && m_Cy >= m_y - 300.0f && m_Cy <= m_y + 300.0f && m_Cz >= m_z - 300.0f && m_Cz <= m_z + 300.0f)
return true;
}

}

return false;

}
Edited by Cydriic

#### Share this post

##### Share on other sites

• Advertisement
• Advertisement

• ### Popular Contributors

1. 1
Rutin
46
2. 2
3. 3
4. 4
5. 5
• Advertisement

• 13
• 10
• 12
• 10
• 13
• ### Forum Statistics

• Total Topics
632995
• Total Posts
3009773
• ### Who's Online (See full list)

There are no registered users currently online

×

## Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!