Checking a Height Value Repeatedly

Started by
13 comments, last by Josheir 5 years, 2 months ago

This question concerns OpenGL.  I have found some code for checking the y value with a grid to place an object on a mesh (a type of collision detection).  However, I want to check the height over and over again to change the velocity of the ball depending on the height of the changing y value.  How do I repeatedly check every height, or is there a different way?  I'm using C++.

Thanks,

Josheir

Advertisement

The question is very unclear, you would probably benefit from adding one or several diagrams, and a link to this code you have found.

In addition to what lawnjelly said, unless there's some aspect of the problem you haven't mentioned, it doesn't sound like the problem concerns OpenGL. That may be causing some confusion, so perhaps reframing the question without reference to OpenGL might help clarify things (assuming it's not in fact OpenGL-related). Perhaps you could also clarify what you mean by 'repeatedly check every height'.

Thank you for the criticism.  Here is the code.  It is explained below, sorry about that.


public float getHeightOfTerrain(float worldX, float worldZ)   {
float terrainX = worldX - this.x;
float terrainZ = worldZ - this.z;
float gridSquareSize = SIZE / ((float) heights.length - 1);
int gridX = (int) Math.floor(terrainX / gridSquareSize);
int gridZ = (int) Math.floor(terrainZ/ gridSquareSize;)
if(gridX >= heights.length - 1 || gridZ >= heights.length - 1 || gridZ < 0 || gridZ < 0) {
return 0;
}
float xCoord = (terrainX % gridSquareSize) / gridSquareSize;
float zCoord = (terrainZ % gridSquareSize) / gridSquareSize;
float answer;
if (xCoord <= (1-zCoord)) {
answer = Maths.barryCentric(new Vector3f(0, heights[gridX][gridZ], 0), new Vector3f(1,
	heights[gridX + 1][gridZ], 0), new Vector3f(0,
	heights[gridX][gridZ + 1], 1), new Vector2f(xCoord, zCoord));
	} else {
answer = Maths.barryCentric(new Vector3f(1, heights[gridX + 1][gridZ], 0), new Vector3f(1,
	heights[gridX + 1][gridZ + 1], 1), new Vector3f(0,
	heights[gridX][gridZ + 1], 1), new Vector2f(xCoord, zCoord));
	}

public static float barryCentric(Vector3f p1, Vector3f p2, Vector3f p3, Vector2f pos) {
		float det = (p2.z - p3.z) * (p1.x - p3.x) + (p3.x - p2.x) * (p1.z - p3.z);
		float l1 = ((p2.z - p3.z) * (pos.x - p3.x) + (p3.x - p2.x) * (pos.y - p3.z)) / det;
		float l2 = ((p3.z - p1.z) * (pos.x - p3.x) + (p1.x - p3.x) * (pos.y - p3.z)) / det;
		float l3 = 1.0f - l1 - l2;
		return l1 * p1.y + l2 * p2.y + l3 * p3.y;
	}

The first two lines of the first code function are explained at the following link (It's not needed in this example and is for multiple terrains; terrainx and terrainy will have the value of zero).  https://www.gamedev.net/forums/topic/701121-very-easy-beginners-question-opengl/ 

I am using the top function to get any height by passing in world coordinates.  The height array holds the heights by there x and z indexes when the terrain was made.

This is what the top function doing

The actual cell is determined by gridx and gridz.

The actual coordinates are than found.

Than the included cellexplanation.gif diagrams formula Is used to determine which triangle cell in the regular square cell.

The height is than determined using the Barry Centric formula.

 

The uploaded image : gridcomplete.gif illustrates my problem.  If there is an incline or decline than there are changing height values when moving from cell A to cell B.  If I am in cell A and I do not pass the unknown smallest amount of x and z and I move into cell B than I have missed some changes of height that I would like to use to change the velocity of the moving object.

I am looking to determine the minimum value so that I can keep using the entirety of the heights to determine the object's speed, if this is possible.  I don't know the minimal unit of measuring, or how it would be determined.  I read everything I could find about world  coordinates and pixels.

Or, maybe interpolation is needed and if so I would appreciate some super pseudocode and/or help.  The cell structure is below in :  cellexplanation.gif;

Otherwise, I'd like to here about any other methods that are not to difficult for a new Graphics Programmer.

 

Hopefully this is more understandable,

Josheir

 

Cite:  tutorial 22 :  

 

gridcomplete.gif

cellexplanation.gif

Ok, so you want to collide a ball against a regular terrain mesh. Off the top of my head:

You can either do it cheap and nasty, or accurately.

  • Cheap and nasty, just use your existing routine to find the ground height under the predicted centre. If this is less than the radius, you have a collision. Use the triangle normal to reflect.
  • More accurate, you could use sphere -> triangle collision (perhaps a swept test) against the surrounding triangles, find the nearest collision, and reflect off that. You probably want some kind of optimized way of finding the triangles to test. The number of triangles to test will depend on the radius of the ball relative to the size of the triangles.

This is assuming you know how to structure some basic ball physics. If not, I would start there before getting into complex collision detection. You may need to fine tune if you use the second option to prevent thing like bouncing off triangle edges.

Or alternatively, use a physics / collision library engine, which is what a lot of people would recommend because this stuff is usually more fiddly than you think.

Also I've seen a couple of recommendations for this paper (not read it myself):

http://www.peroxide.dk/papers/collision/collision.pdf

I already understand the collision against the mesh.  I am in need of  the minimum amount for world coordinate (equals 1 pixel) or help with interpolation pseudocode.  Or maybe something else, like a face vector or something, but I want to keep it easy.  As I explained above with illustrations.

Thanks,

Josheir

The ball will just move over the terrain except it will slow down and go faster, is the idea.

Josheir

The ball will just move over the terrain except it will slow down and go faster, is the idea.

Josheir

The ball will just move over the terrain except it will slow down and go faster, is the idea.

Josheir

i.e. :   If next height is greater slow down some more.

"oops, I missed a height, what do I do?!?!" - get it?

 

Ah I get you now, sorry it was probably difficult to get the idea across for the question. :)

Ok 2 approaches jumping out:

  1. Move the ball (x, z) a 'medium' distance, find the height there, and use the difference in height (gradient) to decide how far to move then ball .. repeat the move but for the calculated distance. Or use it to determine a multiplier to apply to the velocity (depends on your game design).
  2. Find the dot product between the colliding unit triangle normal and a unit vector upwards (0, 1, 0 if using y as up). This gives you a measure of the angle with 1 being the result if the triangle points up, 0 if pointing to the side, and -1 if pointing down. I *think* from memory the angle itself is the arccos of the dot product but you should double check that as I'm tired. You could also want to calculate vertex normals and interpolate these using barycentric method for more smoothness to the gradient across the triangles.

Golly, I think it's great?  Josheir is tired out.

Thank you.

I shouldn't post when tired lol:

Slight modification to 2) .. I didn't take account that the gradient depends on which direction the ball is currently rolling in. If you want to fix the direction of roll, you could do a dot product between a unit vector of the direction of travel and the triangle normal. If you want the ball to roll downhill even if it not the direction you are pushing it in, you can use a conventional collision response 'bounce / slide'.

This topic is closed to new replies.

Advertisement