Collision detection woes

This is a discussion on Collision detection woes within the Game Programming forums, part of the General Programming Boards category; OK, before I start I need to tell you something: I have no experience with linear algebra . I am ...

Collision detection woes

OK, before I start I need to tell you something: I have no experience with linear algebra . I am pretty good at programming, and regular algebra, but I am totally clueless about the linear stuff.

I have several flat quads, at 90º angles. I need some balls to bounce off them

Here goes: My collision detection just don't work. It's as if it's not there. Let me show you a few code samples:

Definition of some types first:
- point3d holds a 3d point
- plane3d is not really a plane. It's got point 3d points[4] for holding a quad, float normal x, y, z for the plane normal, and float distance for the plane distance

Where PLANE_FRONT, PLANE_BACK, and PLANE_COINCIDE are 99, 100, and 101, repectively. But the values don't really matter; as long as they're different.

Now, I know that the ball will always be inside the walls (the 4 walls enclose the ball), so that means that I can skip the process of finding where exactly the collision point on the plane is, right?

All that is left is to find which wall it hit, and then reverse the correct axis:

Code:

void ball_collision(ball *theball) {
// note that we don't actually make sure that the collision point is on the quad; because this
// is such a simple game, that's all the checking we need to do :)
point3d &current_pos = theball->pos; // grab the ball's current position
point3d dest_pos; // this will hold where the ball would go
// from the current velocity, calculate where the ball would go (its destination)
dest_pos.x = theball->pos.x + theball->vel.x;
dest_pos.y = theball->pos.y + theball->vel.y;
dest_pos.z = theball->pos.z + theball->vel.z;
// run through each plane in tube
for (int i=0; i<4; i++) {
int dest_side = classify_point(&tube[i], &dest_pos);
int current_side = classify_point(&tube[i], &current_pos);
// check to see if the destintation point and the current point are on the same sides of the plane (quad)
if (dest_side != current_side) {
// find which wall it collided into
if (i == 0 || i == 2) {
// ball collided on the y axis, so reverse it
theball->pos.y = -theball->pos.y;
return;
}
else {
// ball collided on the x axis
theball->pos.x = -theball->pos.x;
return;
}
}
// keep going
}
}

Where tube is really plane3d tube[4], and so notice that I check to see which wall of the tube it collided into before reversing the appropriate axis. (tube[0] and tube[2] are the bottom and top, respectively. And of course tube[1] and tube[3] are the left and back, respectively.)

But whenever I run the program, the ball keeps going through the walls as if I was never calling the functions. I looked at what the variables are doing, and classify_point always returns PLANE_FRONT, even when the ball is going to fly into the wall.

that doesn't seem right to me. What is the distance exactly; the way you compute it seems to be some sort of variant of a cross product, could you explain the math for me? That aside, you can figure out which side it's on without it:

This is my collision detection primitives library. AFAIK everything works, not everything is neat or optimized. Some of this might rely on other precompiled constructs which you do not have, I leave you to sort through it.

I know I just dumped a mound of crap on you like that, but it seems that, while you claim to not understand it, you've thought about it a bit and are familiar with a bunch of the terminology.

Feel free to ask me more pointed detailed questions about any of those functions. I also have code for doing swept collisions against brushes, but I don't use it anymore. Everything I've posted above can likely be found in tutorials. coldet is something I've got down pretty good, from the implementation side of it. Also, I believe there are coldet libraries out there, nobody would look down upon you for using them (I'm not sure if novodex physics includes coldet). Coldet is one of those nasty required things that is incredibly difficult to actually get to friggin work.

this is how I compile the constructs for the first function in the list of functions I posted above (bool PointInBSPFace()). It pre compiles inward pointing planes for each bsp face (which can be comprised of many triangles). It finds the unique edges and generates planes out of them, so if it was a quad made of up 2 render triangles, it would find the outer 4 edges and generate them into planes. I use this instead of brushes.

As with everything I write it's ugly and hackish, I was probably drunk when I wrote it, and it works.

/*
Step1: Add all edges to a vector
Step2: Go through and count how many triangles have this edge
Step3: All edges that are only owned by 1 triangle are outside edges,
add these to a separate vector
Step4: Compute the inward facing planes using the unique outside edges
*/

I know I just dumped a mound of crap on you like that, but it seems that, while you claim to not understand it, you've thought about it a bit and are familiar with a bunch of the terminology.

Well, the extent of my 3D math knowledge has been learned from the Win95GPE and NeHe. So, I can understand things a bit, but I should really take a linear algebra course if I want to get serious about 3D programming.