[fixed] Collision bug fix

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

[fixed] Collision bug fix

Post by Spintz »

In CSceneCollisionManager.cpp, change the function getCollisionPoint to this -

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! :D
Last edited by Spintz on Thu Sep 15, 2005 12:31 am, edited 2 times in total.
Image
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

BTW, I checked the paper by Kasper Fauerby and the function is correct, as he has listed in the paper, however, it does not work for all cases and the scope of that funciton is a little beyond me. The extremely minimal speed gain by using that function, is not worth the time to debug it, IMO ( so I won't! :P )
Image
Fred

Post by Fred »

Tries these changes but they made no difference.
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

You'll also need to apply -

http://irrlicht.sourceforge.net/phpBB2/ ... php?t=8773

to fix the FPU precision for accurate collision detections when using DirectX.
Image
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

Found one other small change needed in aabbox3d.h

Replace this function -

Code: Select all

//! Tests if the box intersects with a line
//! \return Returns true if there is an intersection and false if not.
bool intersectsWithLine(const vector3d<T>& linemiddle, 
						const vector3d<T>& linevect,
						T halflength) const
{
	const vector3d<T> e = getExtent(); 
	const vector3d<T> t = getCenter() - linemiddle;
	float r;

	if ((fabs(t.X) > e.X + halflength * fabs(linevect.X)) || 
		(fabs(t.Y) > e.Y + halflength * fabs(linevect.Y)) ||
		(fabs(t.Z) > e.Z + halflength * fabs(linevect.Z)) )
		return false;

	r = e.Y * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.Y);
	if (fabs(t.Y*linevect.Z - t.Z*linevect.Y) > r )
		return false;

	r = e.X * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.X);
	if (fabs(t.Z*linevect.X - t.X*linevect.Z) > r )
		return false;

	r = e.X * (T)fabs(linevect.Y) + e.Y * (T)fabs(linevect.X);
	if (fabs(t.X*linevect.Y - t.Y*linevect.X) > r)
		return false;

	return true;
}
Image
Fred

Post by Fred »

I'll try this out tonight. If this fixes the problem, I hope Niko can fold these changes back into the engine.
bronxbomber92
Posts: 27
Joined: Mon Oct 30, 2006 11:55 pm

Post by bronxbomber92 »

Sorry for bumping this old thread, but I'm confused on exactly what I should change and shouldn't (since all the edits creates moe confusion).
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

I'll re-evaluate the changes and see if they've been implemented in SVN. Let you know results soon...
Image
bronxbomber92
Posts: 27
Joined: Mon Oct 30, 2006 11:55 pm

Post by bronxbomber92 »

Alright, thanks :)
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

I'm still planning on getting to this. Been very busy lately....
Image
bronxbomber92
Posts: 27
Joined: Mon Oct 30, 2006 11:55 pm

Post by bronxbomber92 »

Take your time :)
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

just checked these...
triange3d isOnSameSide, getIntersectionOfPlaneWithLine, and aabbox intersectsWithLine were applied sometime before 1.1

CSceneCollisionManager::getCollisionPoint didn't normalize the ray's vector, i've added this as of the latest svn revision.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

Thanks bitplane :)
Image
bronxbomber92
Posts: 27
Joined: Mon Oct 30, 2006 11:55 pm

Post by bronxbomber92 »

I'm uding the mac version, which I believe to be 1.0... So I don't think those are applied for me.
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

Well, all the code excerpts in this function are what the functions should be. So look at the code in your engine for these functions. If it's not the same, make it like these!
Image
Post Reply