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
-Tom Pereira
About the author
#2
09/04/2007 (9:41 am)
IF you're referring to distance, use the t2dVector... functions to handle the math.
#3
Upon collision, in the "onCollision" function, we create a vertical line at the point of intersection:
We now want to see if this line intersects any of the ground surface's collision poly:
This loops through each of the polygon's lines and checks if there is an intersection. Finally, the intersection code:
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
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
Torque Owner Thomas Pereira
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.