Heightmap Collision

Started by
13 comments, last by brandonman 16 years, 6 months ago
no I don't. Kind of what I've been looking for so I have my camera just above the height on the terrain it's on on the x and z axes.
Advertisement
You need to access your pHeightMap array wherever the y value for your x value is stored. I see you use a function called Height(). Can you please post the code to that.
bi-FreeSoftware
Quote:Original post by AdamGL
You need to access your pHeightMap array wherever the y value for your x value is stored. I see you use a function called Height(). Can you please post the code to that.


objCamera.mPos.y=Height(pHeightMap, X + STEP_SIZE, Y );

Seeing how X and Y are his loop variables and the same function is called for the vertices it is most likely just a simple lookup in the heightmap without any interpolation. Not quite sure what behaviour is expected from setting the cameras height to the height of the maps (almost) corner vertex. One would expect the cameras x,z to be rounded to the next int at the very least (some might get dizzy from the jumpy cam, though).

Clearly (from the condition and parameters) this is supposed to be inside the for-loop and set the cameras height when the quad beneath it is drawn (obviously can't and mustn't have any effect until the next frame). At least I'm fairly sure it's outside, as X and Y are otherwise needlessly declared outside and I can't find more closing brackets afterwards (hint: indenting is only useful if it's not done at random). Also, the code would become about 10x more readable (and easier to maintain) by adding something like
inline void setColorByHeight(float y).

This should be somewhat semi-readable and maybe even work:
inline void setColorByHeight(float h) {	if(y>220)		glColor3f(1.0f,1.0f,1.0f);	else if (y>190)		glColor3f(0.4f,0.15f,0.12f);	else if (y>150)		glColor3f(0.1f,0.8f,0.1f);	//Uhm... huge gap? Same color as high values on purpose??	//Considered what happens for y>50 && y<151??	else		glColor3f(0.4f,0.15f,0.12f);}void RenderHeightMap(BYTE pHeightMap[]){	int x, y, z;	const int heightOffset = -100;	if(!pHeightMap) return;	glBegin( GL_QUADS );	for (int X = 0; X < (MAP_SIZE-STEP_SIZE); X += STEP_SIZE )	{ //Do NOT just ditch this bracket, unless the inner loop is just 1-2 lines		for (int Y = 0; Y < (MAP_SIZE-STEP_SIZE); Y += STEP_SIZE )		{			// Get The (X, Y, Z) Value For The Bottom Left Vertex			x = X;			z = Y;			y = Height(pHeightMap, x, z);			setColorByHeight(y);			glVertex3i(x, y + heightOffset, z);			// Get The (X, Y, Z) Value For The Top Left Vertex			x = X;			z = Y + STEP_SIZE;			y = Height(pHeightMap, x, z);			setColorByHeight(y);			glVertex3i(x, y + heightOffset, z);			// Get The (X, Y, Z) Value For The Top Right Vertex			x = X + STEP_SIZE;			z = Y + STEP_SIZE;			y = Height(pHeightMap, x, z);			setColorByHeight(y);			glVertex3i(x, y + heightOffset, z);			// Get The (X, Y, Z) Value For The Bottom Right Vertex			x = X + STEP_SIZE;			z = Y;			y = Height(pHeightMap, x, z);			setColorByHeight(y);			glVertex3i(x, y + heightOffset, z);			if(objCamera.mPos.x>x && objCamera.mPos.x<x+STEP_SIZE &&			  objCamera.mPos.z>z && objCamera.mPos.z<z+STEP_SIZE)				objCamera.mPos.y=Height(pHeightMap, x, z);		}	}	glEnd();	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);}
f@dzhttp://festini.device-zero.de
You should really use the setColorByHeight-function as it's easier to read the code then and easier to find bugs or change color values..

And concerning the height problem, you should have a Height function somewhere, if you didnt change the NeHe it looks like this:

int Height(BYTE *pHeightMap, int X, int Y)			// This Returns The Height From A Height Map Index{	int x = X % MAP_SIZE;					// Error Check Our x Value	int y = Y % MAP_SIZE;					// Error Check Our y Value	if(!pHeightMap) return 0;				// Make Sure Our Data Is Valid	return pHeightMap[x + (y * MAP_SIZE)];			// Index Into Our Height Array And Return The Height}


If you'd use this for the y-coordinate of your camera, then it would stay at the same height until X or Z increases and then your camera jumps to the new height.

You should use a bilinear interpolation to make it move smoothly. This approach calculates the current height over the terrain using the 4 height values around it and figures out the height at the current position. The function now takes the exact X and Z-Coordinates of your camera position.

float getHeight(BYTE *pHeightMap, float x, float z){    float temp[4];    float xi,zi;    if(x!=0) xi=floor(x); // get the lower X for Height(..)    else xi=0;    if(z!=0) zi=floor(z); // get the lower Z for Height(..)    else zi=0;    //store the 4 heights next to our position    temp[0]=Height(pHeightMap, static_cast<int>(xi),static_cast<int>(zi));    temp[1]=Height(pHeightMap, static_cast<int>(xi+1),static_cast<int>(zi));    temp[2]=Height(pHeightMap, static_cast<int>(xi+1),static_cast<int>(zi+1));    temp[3]=Height(pHeightMap, static_cast<int>(xi),static_cast<int>(zi+1));    //now for the interpolation    float tx=x-xi;    float tz=z-zi;    float txtz=tx*tz;    //bilinear interpolation to get the current height above the surface    return temp[0]*(1-tz-tx+txtz)+temp[1]*(tx-txtz)+temp[2]*txtz+temp[3]*(tz-txtz);}


And then you just need to call objCamera.mPos.y=getHeight(pHeightMap,objCamera.mPos.x,objCamera.mPos.z) every frame.
Quote:Original post by Caste
You should really use the setColorByHeight-function as it's easier to read the code then and easier to find bugs or change color values..

And concerning the height problem, you should have a Height function somewhere, if you didnt change the NeHe it looks like this:

*** Source Snippet Removed ***

If you'd use this for the y-coordinate of your camera, then it would stay at the same height until X or Z increases and then your camera jumps to the new height.

You should use a bilinear interpolation to make it move smoothly. This approach calculates the current height over the terrain using the 4 height values around it and figures out the height at the current position. The function now takes the exact X and Z-Coordinates of your camera position.

*** Source Snippet Removed ***

And then you just need to call objCamera.mPos.y=getHeight(pHeightMap,objCamera.mPos.x,objCamera.mPos.z) every frame.

Thanks a ton! now I just need to fix the jerkiness of the camera, it's like I'm jerking the mouse up and down, but that should hopefully be easily fixed! rating+=1 :)

This topic is closed to new replies.

Advertisement