Game Development Community

Collision Depth

by Thomas Pereira · in Torque Game Builder · 01/24/2007 (12:09 pm) · 3 replies

Does the current collision system have any way to detect collision depth? If not, any clever ideas to getting it? Thanks.


-Tom Pereira

#1
01/24/2007 (2:37 pm)
I believe I've figured this out...my little solution is simple.

I get a collision,save the x/y, predict where the object will be next movement cycle, and I've got the depth. Can also remove the prediction and make a second object on the second collision, get the time from the second collision - time from first, and can calculate the depth there - which could be a little faster, but a little choppier.
#2
09/04/2007 (9:41 am)
IF you're referring to distance, use the t2dVector... functions to handle the math.
#3
09/25/2007 (7:50 pm)
I've found a nice way of doing this, however, I am assuming that your collision will be on the y-axis, you could easily modify this to check the x-axis as well.

Upon collision, in the "onCollision" function, we create a vertical line at the point of intersection:

%buffer = 2;
%cpa = getWord(%points, 0) SPC (getWord(%points, 1) - %buffer);
%cpb = getWord(%points, 0) SPC (getWord(%points, 1) + %buffer);

We now want to see if this line intersects any of the ground surface's collision poly:

%collisionPoly = %dstObject.getCollisionPoly();
%polyCount = %dstObject.getCollisionPolyCount();
	
%minY = NULL;
%peny = NULL;

for (%i=0;%i<%polyCount;%i++)
{
	%j = %i + 1;
	if (%i == %polyCount - 1)
		%j = 0;

	%currPoint = %dstObject.getWorldPoint(getWord(%collisionPoly, 2*%i), getWord(%collisionPoly, 2*%i + 1));
	%nextPoint = %dstObject.getWorldPoint(getWord(%collisionPoly, 2*%j), getWord(%collisionPoly, 2*%j + 1));
		
	%collisionTest = checkIntersection(%dstObject, %currPoint, %nextPoint, %cpa, %cpb);
	if (getWord(%collisionTest, 0) && (%minY $= NULL || getWord(%collisionTest, 2) < %minY))
	{
		%minY = getWord(%collisionTest, 2);
		%peny = getWord(%collisionTest, 6) + %buffer;
	}
}

This loops through each of the polygon's lines and checks if there is an intersection. Finally, the intersection code:

function checkIntersection(%groundObject, %pA, %pB, %pC, %pD)
{
	%x1 = getWord(%pA, 0);
	%x2 = getWord(%pB, 0);
	%x3 = getWord(%pC, 0);
	%x4 = getWord(%pD, 0);

	%y1 = getWord(%pA, 1);
	%y2 = getWord(%pB, 1);
	%y3 = getWord(%pC, 1);
	%y4 = getWord(%pD, 1);
	
	%d = (%y4-%y3)*(%x2-%x1) - (%x4-%x3)*(%y2-%y1);
	
	if (%d != 0)
	{
		%ua = ((%x4-%x3)*(%y1-%y3) - (%y4-%y3)*(%x1-%x3))/%d;
		%ub = ((%x2-%x1)*(%y1-%y3) - (%y2-%y1)*(%x1-%x3))/%d;
		
		if (%ua > 0 && %ub > 0 && %ua < 1 && %ub < 1)
		{
			%dx = (%x1 - %x2)/(%groundObject.getSizeX()/2);
			%dy = (%y1 - %y2)/(%groundObject.getSizeY()/2);
			
			%dx = %dx*(%groundObject.getSizeX()/%groundObject.getSizeY());

			%dir = 1;
			if (%y1 < %y2)
				%dir = -1;

			%h = mSqrt(mPow(%dx, 2) + mPow(%dy, 2));

			%cn = -%dy/%h SPC %dx/%h;

			%cx = %x1 + %ua*(%x2 - %x1);
			%cy = %y1 + %ua*(%y2 - %y1);
			
			%penx = %x3 - %cx;
			%peny = %y3 - %cy;

			return 1 SPC %cx SPC %cy SPC %cn SPC %penx SPC %peny;
		}
	}
	
	return false;
}

This function just uses basic maths to find if there is an intersection, then find the point, the normal between the points, and the penetration for each of the x and y axis.

If %peny = 0, there is no penetration. Otherwise, there is!

I hope it helps mate.
Phil