0
\$\begingroup\$

I am trying to implement collision detection system in opengl and c++ and I have a few qustions about best directions. I will just explain my ideas.

So, I have a cube and a sphere as a basic collision example. Well, maybe more basic example would be two spheres but let us ust go with this. So, main idea is to check the distance between cube faces and a sphere. Idea of checking the distance from some plain is mathematically clear to me, but in practice, I have to give my vertices to gpu and then do transformations there. So, what I could do, I could transform my vertices on cpu side also, but obviously this would be done just for the vertices, not for all the points. So I could know where my cube is and where are all the corners. So, I can check if I am above any cube side and if I am I can check if I am colliding with it. But what I can't check is what is exact point of collision since I do not have every point on cpu side tracked. If I want to have realistic collisions I would need to know this in order to calculate cube rotation and translation. So should I solve plane/line intersections or what? Should I maintain an equation for each plane of the cube and solve for intersections to know exact spot? Of course, I would do this only after being sure that I am colliding with that plane. Basicaly, what is the best way of manipulating data on cpu side to keep track of everything?

\$\endgroup\$
7
  • \$\begingroup\$ Why don't you do the collision detection on the cpu? \$\endgroup\$
    – Vaillancourt
    Dec 7, 2022 at 11:02
  • \$\begingroup\$ I am, I am trying to do it on the cpu but as I said, I don't know how is it done in practice, regarding how to get the data about where in space collision objects are exactly... \$\endgroup\$ Dec 7, 2022 at 11:03
  • \$\begingroup\$ Ah, well you keep a transformation matrix for each of your objects which is used to transform it from local frame to global frame! Each frame, the transform will be updated based on physics, and the matrix will be uploaded to the GPU so that the vertices can be drawn at the right place. \$\endgroup\$
    – Vaillancourt
    Dec 7, 2022 at 11:36
  • \$\begingroup\$ You usually would not process cube-sphere collisions using individual vertices and faces. You'd transform the sphere's center into the cube's coordinate system using the world-to-local matrix you have CPU-side, clamp this to the closest point on the cube using its size in each dimension, then compare the distance to the sphere's radius. If less, you can take the closest point you computer as the contact. OpenGL is not involved in any step of that process. Where have you encountered difficulty implementing this? \$\endgroup\$
    – DMGregory
    Dec 7, 2022 at 15:15
  • \$\begingroup\$ I don't think I was clear. So, I know that I should check the distance of the sphere center from the cube. That part is clear. But the rest of your explanation is welcome, although somewhat unclear. So when you say that I would transform sphere center into cube coordinate system, do you mean the coordinate system in which cube center is at its origin and cube sides are parallel to ones defined by coordinate system axis? So I would actually need to apply inverse of a view*model matrix and apply it on the sphere center, and I already know cube vertices in this coordinate system? \$\endgroup\$ Dec 7, 2022 at 16:22

1 Answer 1

1
\$\begingroup\$

The whole process involved in what you want to do is too broad for the context of a StackExchange question, so I'll cover broadly what you're looking for.

As it's been said in the comments, collision detection is not done on the GPU. The GPU is not aware of the concept of physics, it cares only about the graphics (¬), so you'll want to process the physics on the CPU and then send the results to the GPU (through a matrix) so that it shows correctly the world state. Alternatively, the physics engine does not care about the GPU or what the users sees (and how they see it).

To do that, you need a part of your code to only care about physics. Let's say you have two primitives:

  • cube
  • sphere

You need a way to define those items; for a cube it's its length, and for a sphere, it's the radius. You can assume that those are centered at the origin, so the vertices of the cube, in local frame are situated at ±l/2 where l is the length of the cube.

Then you'll need to know how those are positioned in the world, so you add to each of those a transform matrix used to transform the object from local frame to world frame; it is essentially containing the position and the orientation of the object. This is what you'll end up sending to the GPU each frame.

The primitive length/radius and the transform matrix give you all the information you need to know where exactly is the object.

You'll use this information to determine if objects collide. You'll need some functions to tell you if two objects collide (I suggest you look up those using your favourite search engine, it's been implemented many times):

Each frame, you check each pairs of objects using those functions, and if they collide, you then handle the collision in the way you see fit (sometimes, those function will tell you the point(s) of contact and how much they penetrate, along with the axis of penetration, so you can push them out if you want them to only "touch").

¤

That's it. Once you have handled the collisions, the objects are placed at their final location this frame using their transform matrix, so the next physics step is ready to go. It's now time to make your user aware of it: you find a way to send the transform matrix (that's your "model" matrix) to the GPU (AFAIK, you need to set a uniform before drawing your primitive's VAO).


¬ I'm pretty sure some physics can be done on the GPU in some context, but generally speaking in game development, you'll want some parts of your game logic aware of the results of the physics steps (e.g. a bullet has hit an enemy, so you'll want to remove some hit points on the enemy entity), and going from the GPU back to the CPU (where your game logic executes) is not trivial/optimal.

¤ Often, physics engines will have "two phases" when checking for collisions

  • the broad phase, where they roughly check if the two object may be colliding (e.g. using AABB)
  • the narrow phase, if the broad phase concluded that they may be colliding, the narrow phase will actually check more precisely if the two objects collide, and how they collide.
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .