PDA

View Full Version : 3D Detecting Collisons and keep objects seperated (Ball Maze)



mfaorlkzus
06-28-2016, 10:19 AM
Hello,

I'm new to this Forum and I have a real problem with the Android application I want to build. I want to make a game where you have to navigate a ball through a maze by tilting your phone. The borders of the maze is made out of many cubes and the ball is a little, red wireframe sphere (see on the picture below).


To check if they are colliding, I wrote a method which checks if the coordinates (x and z, not y! It can only move in 2d, but it should look 3D) of the ball are within the coordinates of one of the cubes, which are in a list called obstacles:
=> if (ball.xmax >= obstacle.xmin && ball.xmin <= obstacle.xmax && ball.zmax >= obstacle.zmin && ball.zmin <= obstacle.zmax) {...} // every object has xmin, xmax, zmin and zmax representing the 4 edges
This works.
But my problem is that I can't figure out a way to prevent the ball from going inside a wall. It should not bounce off of the walls, the walls just have to act like a barrier so that the ball stays inside the game.


I appreciate every help that you can give me
kind regard,
Markus

mfaorlkzus
06-28-2016, 10:21 AM
Here is the picture

markusfolz.de/img/picture_01.jpg

GClements
06-28-2016, 02:30 PM
You can take a look at this (http://www.zen87603.zen.co.uk/webgl/glmaze/glmaze.html) for a working example (albeit 2D rather than 3D, and in JavaScript).

The basic idea is that you need to find the point in time (t) at which a ray P+t*D intersects a surface, where P is the current position of the ball's centre and D is the direction of motion.

To find the point of intersection of a moving ball with a face, you need to find the where the centre of the ball intersects the face offset by the ball's radius in the direction of the face's outward-facing normal.

To find the point of intersection of a moving ball with the edge (corner) between two faces, you need to find where the centre of the ball intersects a cylinder whose axis is the edge and whose radius is equal to the ball's radius.

To find the point of intersection of a moving ball with the corner where three faces meet, you need to find where the centre of the ball intersects a sphere whose centre is the corner and whose radius is equal to the ball's radius. The example linked above doesn't cover this case because it isn't applicable in 2D.

In the first two cases, you also need to perform a bounds check. E.g. detecting the intersection of a ray with a polygon involves first detecting the intersection of a ray with the polygon's plane, then confirming that the point of intersection is within the polygon itself. Similarly, detecting the intersection of a ray with a finite cylinder involves first detecting the intersection with an infinite cylinder then confirming that the point of intersection is within the finite section.

Once you can do the above, it's just a matter of testing for intersection with each surface. In practice, you'll want some form of "broad phase" detection which excludes most of the surfaces quickly, so that you're not performing relatively complex calculations for every surface every frame. Once you've determined which surfaces the ray intersects and (most importantly) the time t at which intersection occurs, it's now a matter of finding the first collision, i.e. the one with the smallest positive t.

For robustness, you want to ignore collisions where the dot product between the surface's outward-facing normal and the direction of motion is positive, as this indicates that the ball is initially inside the surface, and you don't want the collision to keep it there.

After processing each collision, you then update the ball's position according to P'=P+t*D, which will place it in contact with the surface. You then update the direction of motion D according to the collision model (you probably want inelastic collision).

Finally, you repeat all of the above steps for the remainder of the time interval, i.e. between the time at which the collision occurred and the end of the frame. This is necessary to correctly handle the case where the ball hits multiple surfaces simultaneously. In the worst case, you may find that it oscillates between two surfaces with a negligible time interval between collisions. If that happens (i.e. the number of iterations for a single frame exceeds some threshold), you should just set D to the zero vector and leave the ball at the point of its last collision.