How to handle collision openGL - c++

This is separate to a previous question I asked.
To make the collision detection simpler I am now using euclidean distance to work out if objects intersect.
I am working in a 3D environment using openGL with bounding walls around the
edges.
I have a player (just displayed as a quad for now)
There are also several randomly displayed cylinders acting as pillars, created using gluCylinder.
Intersection with the walls is fine, and I know that if there is an intersection with the left wall for example the player should be positioned at an X co ordinate that is 0.5 away from the bounding wall.That way if the player is going to go through the wall then it will have the appearance of being able to walk into the wall but not through it.
I am having trouble with the inner pillars, and what i should do with the player when i detect they are within a certain distance of a pillar.
I am using a euclidean distance calculation to detect collisions when diet is < than a value 1 for example.
double dist = sqrt(pow((playerX - xPosi[i]),2) + pow((playerZ - zPosi[i]),2));
xPosi[i] and zPosi[i] are arrays holding the x and z co ordinates of my pillars, and player X and Z hold the co ordinates of the player. Could anyone suggest how to handle the interaction with the pillars, as i now have the collision detection working.
The player will only be travelling in either a +ve or -ve x direction or +ve or -ve z direction, I would like the player to stop if a collision is detected and no longer be able to move through the pillar.

Related

Collision Detection between quads OpenGL

I am making a simple 3D OpenGL game. At the moment I have four bounding walls, a random distribution of internal walls and a simple quad cube for my player.
I want to set up collision detection between the player and all of the walls. This is easy with the bounding walls as i can just check if the x or z coordinate is less than or greater than a value. The problem is with the interior walls. I have a glGenList which holds small rectangular wall segments, at the initial setup i randomly generate an array of x,z co ordinates and translate these wall segments to this position in the draw scene. I have also added a degree of rotation, either 45 or 90 which complicates the collision detection.
Could anyone assist me with how I might go about detecting collisions here. I have the co ordinates for each wall section, the size of each wall section and also the co ordinates of the player.
Would i be looking at a bounded box around the player and walls or is there a better alternative?
I think your question is largely about detecting collision with a wall at an angle, which is essentially the same as "detecting if a point matches a line", which there is an answer for how you do here:
How can I tell if a point belongs to a certain line?
(The code may be C#, but the math behind it applies in any language). You just have to replace the Y in those formulas for Z, since Y appears to not be a factor in your current design.
There has been MANY articles and even books written on how to do "good" collision detection. Part of this, of course, comes down to a "do you want very accurate or very fast code" - for "perfect" simulations, you may sacrifice speed for accuarcy. In most games, of the players body "dents" the wall just a little bit because the player has gone past the wall intersection, that's perhaps acceptable.
It is also useful to "partition the space". The common way for this is "Binary space partitioning", which is nicely described and illustrated here:
http://en.wikipedia.org/wiki/Binary_space_partition
Books on game programming should cover basic principles of collision detection. There is also PLENTY of articles on the web about it, including an entry in wikipedia: http://en.wikipedia.org/wiki/Collision_detection
Short of making a rigid body physics engine, one could use point to plane distance to see if any of the cubes corner points are less than 0.0f away from the plane (I would use FLT_MIN so the points have a little radius to them). You will need to store a normalized 3d vector (vector of length 1.0f) to represent the normal of the plane. If the dot product between the vector from the center of the plane to the point and the plain normal is less than the radius you have a collision. After that, you can take the velocity (the length of the vector) of the cube, multiply it by 0.7f for some energy absorption and store this as the cubes new velocity. Then reflect the normalized velocity vector of the cube over the normal of the plane, then multiply that by the previously calculated new velocity of the cube.
If you really want to get into game physics, grab a pull from this guys github. I've used his book for a Physics for games class. There are some mistakes in the book so be sure to get all code samples from github. He goes through making a mass aggregate physics engine and a rigid body one. I would also brush up on matrices and tensors.

2D Static Box Collision with variable terrain

Im working on a 2D game in which the terrain can vary and is composed of any shape of polygons except for self intersecting ones. The player collision box is in the shape of a square and can move about. My question is this: How do I keep an always-upright box to collide with variable terrain and always stay outside?
My current approach that I made up albeit no code yet works like the following:
The blue square is the player hitbox. First, it moves with a velocity downwards as an example. My goal is to find the heighest point in its travel path where it can be safely outside of the terrain polygon. I test all the terrain vertex points inside its travel path and project them to the velocity of the box. I take the farthest projection.
The farthest projection will be the max distance allowed to move in without going into the terrain.
Move the square by distance in the direction of velocity and done.
However, there are few scenarios that I encountered where this does not work. Take this as an example:
To remedy this situation, I now test for one corner of the square. If the distance from the corner is shorter than the farthest projection, then that distance will give the appropriate shift in distance. This pretty much makes the algorithm full-proof. Unless someone states another exception.
Im going a little crazy and I would appreciate feedback on my algorithm. If anyone has any suggestions or good reads about 2D upright box collisions on terrain or anything similar, that would be great.
This may be useful, and here I'll quickly elaborate on "upright" square collision.
First the collision may occur on the side of the square, and not necessarily a corner. A simple solution to check any collision is describe the region delimited by the square, and then check if any point of your uneven terrain is within this region.
To define the square region, assume your upright square is has the corners (x1,y1), (x2,y1), (x2,y2), (x1,y2), where x2>x1 and y2>y1. Then for a point (x,y) to be within the square it needs to satisfy the conditions
If( x1< x < x2 and y1< y <y2) Then (x,y) is in the square.
Then to conclude, all you need do is check if any point on the terrain satisfies the above condition.
Good luck.

Finding the angle of a coordinate inside a circle

Right down to business, basically I am making a small mini game which has characters running on top of a flat clock with the clock hand rotating around, the characters have to avoid it by jumping.
the part im struggling with is coding the collision, the clock hand is just a set model that is rotated applying matrices and for whatever reason box collision will not work.
So my theory is because i know the angle that the clock hand is currently being multiplied by, is there some mathematical way to calculate the angle of the player in relation to the centre point of the circle so that this can be checked against the clock hand angle?
Sure.
float angle = atan2(y_handle - y_center, x_handle - x_center);

2D collsion detection in arc

I need to implement 2D collision detection by arc. I have player(black dot) and enemies(red dots). Player can attack in any direction and his hit area is 120 degrees(green lines show it) and certain radius(black curve).
How to achieve this detection?
I have done code where angle is calculated between player and enemy but i cant understand how to use player's direction vector to check if it inside arc.
Calculate the angle to the enemy and the distance away they are. Use this to check if they are in range.
The problem is simple if the area where a square since you are using Cartesian coordinates so by converting to radial coordinates, this problem becomes simple too.
With new information
Vector A is the player's direction vector.
Calculate a vector B from the enemy to the player.
Check the length of vector B isn't too long.
Then angle between the vectors is given by: acos(|A.B| / |A||B|)
If the angle is less than 60 degrees (half the 120) then the enemy is in range.
First of all the player must have a direction, a 2D vector for example. In simple it's angle with the first green line = it's angle with the other green line.
You should perform two checks:
Check if the distance between the enemy and the player is less than the radius, if not, move to the next enemy, if yes then
Draw a virtual line between the player and the enemy and calculate the angle between this line and the the direction of the player, if it's less than the half of hit-area-angle (in your example, if it's less than 60) then the player CAN hit the enemy, if not move to the next one.
That should be enough as an idea, hope that's helpful.
Let's say you have unit-length vector pointing "forward". And let's say you have unit length vector pointing to potential target. If target is within ark, then;
dot(forwardVector, targetVector) >= cosf(arcAngle/2).
If vectors aren't unit length, it won't work, of course. That checks if the target is within required angle.
Checking if it is within required distance is trivial and is pretty much squaredLength(targetPosition - playerPosition) <= arkDistance*arkDistance where squaredLength is dot(vector, vector).

How can you deflect a direction/magnitude vector based on a direction/magnitude vector and a collided triangle?

So, I have a Triangle->AABB collision algorithm and I have it returning the triangle that the AABB collided with. I was hoping with the 3 vectors of the triangle and the direction/magnitude of the movement would let me determine a deflected vector so that when you run against the wall at an angle you move slower, depending on the angle of collision, but along side the wall. This would remove the sticky collision problem with only moving when there is not a collision. Any suggestions or references would be greatly appreciated! Thanks.
First, I would convert magnitude/direction to a vector (it's much more convenient).
Then (c++):
float towards=dot(velocity,norm); // velocity component into triangle
if(towards<0) // is moving into triangle
velocity-=towards*norm; // remove component
Then it can't move into the triangle. towards<0 might need to be reversed depending on your normal. It's also nice to have a spring force pushing it out.
Remove the component of the velocity along the normal of the triangle.
The idea is that you can represent the movement as the part that's moving "into" the triangle and the remainder (which will be in perpendicular directions). If you then just move with the remainder, you will no longer be getting any closer to the triangle by the movement (or further, but you shouldn't be detecting a collision in that case).
In pseudo-code:
// v := velocity vector of moving object
// p[3] := points that make up the triangle
triangle_normal = cross(p[2]-p[0], p[1]-p[0])
problematic_v = project(v, onto=triangle_normal)
safe_movement = v - problematic_movement
Note that this intentionally doesn't preserve the magnitude of the movement vector, as doing so would make you slide along a wall very quickly when running straight at it.
For more details and some nice pictures, see Pool Hall Lessons: Fast, Accurate Collision Detection Between Circles or Spheres at Gamasutra. You're not using spheres, but you are essentially doing a perfectly plastic (since you don't bounce) collision.