• 13
• 18
• 19
• 27
• 10

# Intersection on boundingboxes with raycasting

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

## Recommended Posts

Hey, I'm trying to get raycasting to work to see if it intersects with a boundingbox, the code below here is what i have so far which calculates the ray and checks for intersection. problem is.. it's not working! the values i get from the calculation seem to be alright, and i think the main problem is in the intersection test. my engine is abstract so i'm trying to avoid any direct DX in here. i would like to have some kind of functionality like the D3DXBoxBoundProbe where i can specify my origin, direction and BB info. any help would be much appriciated :)
// Build the ray with the mouse position
void Ray::createRay(int mouseX, int mouseY, Matrix* mProjMatrix, Matrix* mViewMatrix, Matrix* mWorldMatrix)
{
// Calculate projection stuff
v.x = ((( 2.0f*mouseX) / 640.0f)  - 1.0f) / mProjMatrix->_11;
v.y = (((-2.0f*mouseY) / 480.0f) + 1.0f) / mProjMatrix->_22;
v.z = 1.0f;

Matrix* mInverse;

mInverse = &mViewMatrix->Inverse();

// Transform the screen space pick ray into 3D space
vDirection.x  = v.x * mInverse->_11 + v.y * mInverse->_21 + v.z * mInverse->_31;
vDirection.y  = v.x * mInverse->_12 + v.y * mInverse->_22 + v.z * mInverse->_32;
vDirection.z  = v.x * mInverse->_13 + v.y * mInverse->_23 + v.z * mInverse->_33;

vOrigin.x = mInverse->_41;
vOrigin.y = mInverse->_42;
vOrigin.z = mInverse->_43;

Matrix* Matinverse;
Matinverse = &mWorldMatrix->Inverse();

//rayObjOrigin = Matinverse->TransformVectorByMatrix(&vOrigin); not working yet
rayObjOrigin.x = vOrigin.x * Matinverse->_11 + vOrigin.y * Matinverse->_21 + vOrigin.z * Matinverse->_31 + Matinverse->_41;
rayObjOrigin.y = vOrigin.x * Matinverse->_12 + vOrigin.y * Matinverse->_22 + vOrigin.z * Matinverse->_32 + Matinverse->_42;
rayObjOrigin.z = vOrigin.x * Matinverse->_13 + vOrigin.y * Matinverse->_23 + vOrigin.z * Matinverse->_33 + Matinverse->_43;

//rayObjeDirection = Matinverse->TransformVectorNormalByMatrix(&vDirection); not working yet
rayObjeDirection.x = vDirection.x * Matinverse->_11 + vDirection.y * Matinverse->_21 + vDirection.z * Matinverse->_31;
rayObjeDirection.y = vDirection.x * Matinverse->_12 + vDirection.y * Matinverse->_22 + vDirection.z * Matinverse->_32;
rayObjeDirection.z = vDirection.x * Matinverse->_13 + vDirection.y * Matinverse->_23 + vDirection.z * Matinverse->_33;

rayObjeDirection.Normalize();

}

// Now we check to see if we are going through anything
bool Ray::checkCollisionAtBB(BoundingBox* box)
{
// By default we don't hit
bool hit = false;

// First grab the entity's bounding box
Vector boxPos;
Vector diff;

// Now calculate the position of the box
// We have the two corners of the box so we only need to calculate the average
boxPos.x = ((box->minX + box->maxX) / 2.0f);
boxPos.y = ((box->minY + box->maxY) / 2.0f);
boxPos.z = ((box->minZ + box->maxZ) / 2.0f);

// Now calculate width and height
// NOTE: Not sure how to use boxes rather than spheres for checking collision, yet...
float boxWidth = box->maxX - box->minX;
float boxLength = box->maxZ - box->minZ;
float boxHeight = box->maxY - box->minY;

// Make sure the above values are positive
if(boxWidth < 0){boxWidth = 0 - boxWidth;}
if(boxLength < 0){boxLength = 0 - boxLength;}
if(boxHeight < 0){boxHeight = 0 - boxHeight;}

// Create a new vector
diff.x = (this->rayObjOrigin.x - boxPos.x);
diff.y = (this->rayObjOrigin.y - boxPos.y);
diff.z = (this->rayObjOrigin.z - boxPos.z);

// Calculate the dot products
float dotA = 2.0f * this->rayObjeDirection.DotProduct(diff);
float dotB = diff.DotProduct(diff) - (boxWidth * boxLength);

// Discrimant thingy-ma-jiggy, who comes up with this shit...
float fDiscriminant = (dotA * dotA) - (4.0f * dotB);

// Check discrimant
if(fDiscriminant > 0.0f)
{
// Square root
fDiscriminant = sqrtf(fDiscriminant);

float fSearchA = (-dotA + fDiscriminant) / 2.0f;
float fSearchB = (-dotA - fDiscriminant) / 2.0f;

// If it's larger than 0.0f, we've hit something
if(fSearchA >= 0.0f || fSearchB >= 0.0f)
{
// Set to true
hit = true;
}
}

// Return result
return hit;
}



##### Share on other sites
Quote:
 // Discrimant thingy-ma-jiggy, who comes up with this shit...

Maybe you should try understanding AABB-ray intersection testing ;)

A couple of things I noticed looking at your code.

You hard-code 640×480 as the display size ... this is not the source of your problem but it is a bad idea. At the very least these ought to be constants defined in one place, not sprinkled throughout your code.

Your difference vector is from the box centre to the ray. I would expect it to be the other way around. This will cause rayObjeDirection.DotProduct(diff) to be negative and therefore the test to fail (though you might hit things directly opposite where you are aiming, i.e. behind you somewhere).

I don't entirely understand the hit test you are doing either but I think it is a ray-sphere test not a ray-AABB test. It doesn't look right though, you are not taking account of the diminishing size of the sphere at distance. An approximate test would be: