- Code: Select all
//! Finds the collision point of a line and lots of triangles, if there is one.
bool CSceneCollisionManager::getCollisionPoint(const core::line3d<f32>& ray,
ITriangleSelector* selector, core::vector3df& outIntersection,
core::triangle3df& outTriangle)
{
if (!selector)
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return false;
}
s32 totalcnt = selector->getTriangleCount();
Triangles.set_used(totalcnt);
s32 cnt = 0;
selector->getTriangles(Triangles.pointer(), totalcnt, cnt, ray);
core::vector3df linevect = ray.getVector().normalize();
core::vector3df intersection;
f32 nearest = 9999999999999.0f;
bool found = false;
f32 tmp;
for( s32 i = 0; i < cnt; ++i )
{
if( Triangles[i].getIntersectionWithLine( ray.start, linevect, intersection ) )
{
if( intersection.isBetweenPoints( ray.start, ray.end ) )
{
tmp = (f32)intersection.getDistanceFromSQ( ray.start );
if( tmp < nearest )
{
nearest = tmp;
outTriangle = Triangles[i];
outIntersection = intersection;
found = true;
}
}
}
}
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return found;
}
EDIT: The lineVect needs to be normalized for the functions to work properly. The other changes are just minor speed ups.
Also, in triangle3d.h, change the getIntersectionWithLine function to -
EDIT: Don't use isPointInsideFast, I came across a bug with that as well, where not all intersections were returned. If you keep using isPointInside and then fix the isOnSameSide function, it will work perfectly!!!
In triangle3d.h, change isOnSameSide to
- Code: Select all
bool isOnSameSide(const vector3d<T>& p1, const vector3d<T>& p2,
const vector3d<T>& a, const vector3d<T>& b) const
{
vector3d<T> bminusa = b - a;
vector3d<T> cp1 = bminusa.crossProduct(p1 - a);
vector3d<T> cp2 = bminusa.crossProduct(p2 - a);
return (cp1.dotProduct(cp2) >= 0.0f);
}
The single small change in this function, is in the return call, it currently is '>' and should be '>='!!!!
Also in triangle3d.h, change getIntersectionOfPlaneWithLine function to -
- Code: Select all
bool getIntersectionOfPlaneWithLine(const vector3d<T>& linePoint,
const vector3d<T>& lineVect, vector3d<T>& outIntersection) const
{
vector3d<T> normal = getNormal().normalize();
T t2 = normal.dotProduct( lineVect );
if( t2 == 0.0f )
return false;
T d = pointA.dotProduct( normal );
T t = -( normal.dotProduct( linePoint ) - d ) / t2;
outIntersection = linePoint + (lineVect * t);
return true;
}
Here, the normal of the triangle needs to be normalized. getNormal() for a triangle only returns the vector representing the direction the triangle is facing, and does not normalize it!
Happy colliding!

