[fixed] Collision bug fix
Posted: Wed Sep 14, 2005 8:21 pm
In CSceneCollisionManager.cpp, change the function getCollisionPoint to this -
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
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 -
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!
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;
}
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);
}
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;
}
Happy colliding!