Please check my 2D collision Logic!

Started by
3 comments, last by LevyDee 12 years, 6 months ago
I have been having some trouble for the past couple days, and I just wanted to check with you guys if my collision logic is sound.
This logic does work for the most part(I can run into a wall and slide against it), but it is possible for objects to still go through each other if I dink around in game enough.

1.Check if there is a collision on the x axis
2. Check if there is a collision on the z axis

3.if there is a collision on both the x and z axis, the two objects have intersected. (else - simply return and do not adjust any coordinates)
-get the previous location of the bounding coordinates before the intersect occurred. (Note: There are 8 bounding coordinates. My system is an Axis-Aligned Bounding Box)
- Check what axis was previously colliding.

>if x was already colliding, only update the x coordinates
>if z was already colliding, only update the z coordinates

Heres the code. It is commented, so even without knowing what the classes and functions do, hopefully you should be able to follow the logic.

Hint: CBB is collision bounding box

Copy pasting also ruing format alittle, but it is still very readable.



//Check axis collisions
xCollide = _CheckXCollision(&origin->cbb[n], &_cbbWarehouse.GetCBBActiveCollectionAt(i)->cbb[j]);
zCollide = _CheckZCollision(&origin->cbb[n], &_cbbWarehouse.GetCBBActiveCollectionAt(i)->cbb[j]);

//If an intersect has occured, figure out what axis caused it, and revert that axis
if(xCollide && zCollide)
{
//Get previous draw location
D3DXVECTOR3 prevPos = static_cast<BucketItem*>(origin->object)->GetPreviousDrawLocation();

//Get previous CBB location
float adjustedX = (static_cast<BucketItem*>(origin->object)->GetDrawLocation()->x - prevPos.x);
float adjustedZ = (static_cast<BucketItem*>(origin->object)->GetDrawLocation()->z - prevPos.z);
CollisionBoundingBox revertedCBB = origin->cbb[0];
for(int i = 0; i < 8; i++)
{
revertedCBB.boundingCoordinates.x -= adjustedX;
revertedCBB.boundingCoordinates.z -= adjustedZ;
}

//Recheck collision to find what caused the CBB's to intersect
if(_CheckXCollision(&revertedCBB, &_cbbWarehouse.GetCBBActiveCollectionAt(i)->cbb[j]))
{
//If x was already colliding, only update the x coordinate
prevPos.x += adjustedX;
UpdateCBBLocationDelta(adjustedX, 0.0f, -adjustedZ, origin->associatedObjectId);

Error::ReportMessage("X caused collision!");
}

else if(_CheckZCollision(&revertedCBB, &_cbbWarehouse.GetCBBActiveCollectionAt(i)->cbb[j]))
{
//If z was already colliding, only update the z coordinate
prevPos.z += adjustedZ;
UpdateCBBLocationDelta(-adjustedX, 0.0f, adjustedZ, origin->associatedObjectId);

Error::ReportMessage("X caused collision!");
}

//Set the new draw location
static_cast<BucketItem*>(origin->object)->SetDrawLocation(prevPos);



So any initial thoughts on what could be wrong? Thanks!
Advertisement
1: Your topic miss guided me... this is collision response. I know I'm picky.

2: No matter what collision happend, you always report that it happened on the x axis.

3: Despite the fact that you already checked for collisions... and know what collisions happened, you recheck them anyway?

4: You have code to handle seperate collisions.. but it only gets checked if both axis collided?

5: Without seeing how you check for collisions, or better explain why you think this code is wrong, it's hard to help. My guess, you're only checking if something collided after it moved. If something moves fast enough it's going to be able to jump other objects before a collision is checked. A simple line intersect uses the first and last positions would detect if your object collided with anything on it's path.
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
1. This is both detecting and responding =p

2. Explain? How do I always report that that a collision has happened on the x axis?

3. I recheck the previous position before the intersect occured, so I know what axis to update, and what axis to leave alone.

4. If there is only a collision on the x axis, it doesnt matter because the two objects have not intersected.

5. That is my first guess is that it is jumping to fast, but I was looking for other opinions. Also please explain your line intersect example.

Thanks!

2. Explain? How do I always report that that a collision has happened on the x axis?


It's nothing breaking, so I think you finding this on your own, will better you more.


3. I recheck the previous position before the intersect occured, so I know what axis to update, and what axis to leave alone.
[/quote]

You miss interpreted me... though I worded bad. You check the collisions... You should already know what axis collided... why check them again?


4. If there is only a collision on the x axis, it doesnt matter because the two objects have not intersected.
[/quote]

You'll have to post your code detecting collisions, else I'm shooting in the dark on this one. From what I can tell you're doing simple axis aligned bounding box detection... how can only one axis collided?


5. That is my first guess is that it is jumping to fast, but I was looking for other opinions. Also please explain your line intersect example.
Thanks!
[/quote]

Google "line intersects rectangle"

Basically you cast a ray from the box's original position to it's new position. Then test if that line collideds with any object. If it does then your object has collided with something along it's path. You then need to find what object it hit first and respond accordingly.

also, it sorta looks like you store your object as a set of points (lines) anyways, so why not do line-line intersect tests instead. Then you'll get a far more accurate result on the exact point the object collided. Allowing you to apply torque and force on the objects more accurately.
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
Thank you for the response, Ill look into the line intersect!

This topic is closed to new replies.

Advertisement