Archived

This topic is now archived and is closed to further replies.

Getting the height at a location

This topic is 5176 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a quad with four vertices of variable height which is 1 unit square. 2 is 0,0 3 is 1,1
1--3
|  |
|  |
2--4
The first step I''m assuming is to determine which way the quad folds.
v1[0]=(int)x*1.0;
v1[1]=(int)y*1.0+1.0;
v2[0]=(int)x*1.0;
v2[1]=(int)y*1.0;
v3[0]=(int)x*1.0+1.0;
v3[1]=(int)y*1.0+1.0;
v4[0]=(int)x*1.0+1.0;
v4[1]=(int)y*1.0;
v1[2]=height_field[(int)v1[1]][(int)v1[0]];
v2[2]=height_field[(int)v2[1]][(int)v2[0]];
v3[2]=height_field[(int)v3[1]][(int)v3[0]];
v4[2]=height_field[(int)v4[1]][(int)v4[0]];
if((v1[2]+v4[2])/2.0f>(v2[2]+v3[2])/2.0f)
If the height in the center of vertices 1 and 4 are greater then the height in the center of vertices 2 and three the the quad is folded along 1 and 4
-----
|\  |
| \ |
|  \|
-----
Other wise the fold is along 2 and 3
-----
|  /|
| / |
|/  |
-----
And that determines my two planes that I could be standing on. If the height in the center is equal, it doesn''t really matter since the quad is flat so going either way will work since it''s actually a single plane. The next step is to figure out which plane I''m standing on. In case of the first one
if(y-(int)y<1-x+(int)x)
Then I''m on the left plane otherwise I''m on the right plane. In case of the second one
if(y-(int)y>x-(int)x)
I''m on the left plane, otherwise the right. Once it''s determined which plane I''m standing on, the vertices that make up the plane are passed to a function which does the vector math where v2 is the center vertice. Vector v1v2 and v2v3 are used to determine the plane.
float getHeight(float v1[3], float v2[3], float v3[3], float x, float y)
{
	float val;
	val=-((v1[1]-v2[1])*(v3[2]-v2[2])-(v1[2]-v2[2])*(v3[1]-v2[1]))*(x-v2[0]);
	val-=((v1[2]-v2[2])*(v3[1]-v2[1])-(v1[0]-v2[0])*(v3[2]-v2[2]))*(y-v2[1]);
	val/=((v1[0]-v2[0])*(v3[1]-v2[1])-(v1[1]-v2[1])*(v3[0]-v2[0]));
	val+=v2[2];
	return val;
}
This works approximatly well however, although it gets the general solution (in that I can take partial steps around a quad and end up at the right height), moving around results in a jerky motion. I''m thinking it might be the transition between quads that''s confusing it. I was wondering if anyone could spot any obvious errors in my math or suggest a simpler solution. Ben [ IcarusIndie.com | recycledrussianbrides.com | Got Linux? ]
Will Post For Food

Share this post


Link to post
Share on other sites
with a bit of help from The Senshi at

http://www.gamedev.net/community/forums/topic.asp?topic_id=62935

The theory was perfect (figuring out which triangle I was over was amazingly overthought out) but my ability to copy even my own code/equations from paper to PC has yet again been demonstrated as lacking. Getting Y and Z flipped around didn''t help either.

All the equations in the first getHeight can easily be combined into a single return. It''s all laid out for readability.

Senshi uses DirectX functions to get the intersection where I do all the math by hand so the concepts here can be used with anything. I happen to use OpenGL.


float terrainSystem::getHeight(float v1[3], float v2[3], float v3[3], float x, float z)
{
float ax=v2[0]-v1[0];
float ay=v2[1]-v1[1];
float az=v2[2]-v1[2];

float bx=v2[0]-v3[0];
float by=v2[1]-v3[1];
float bz=v2[2]-v3[2];

float c=ay*bz-az*by;
float d=az*bx-ax*bz;
float e=ax*by-ay*bx;

return -(e*(z-v2[2])+c*(x-v2[0]))/d+v2[1];
}

float terrainSystem::getHeight(float x, float z)
{
float v1[3],v2[3],v3[3];
int rx, rz;
rx=x;
rz=z;

if(height_field!=NULL)
if(mapy>0)
if(mapx>0)
if((int)x<mapx-1 && (int)x>=0)
if((int)z<mapy-1 && (int)z>=0)
{
if(z-(int)z > x -(int)x)
{
v1[0]=rx;
v1[1]=height_field[rz+1][rx];
v1[2]=rz+1.0;
v2[0]=rx;
v2[1]=height_field[rz][rx];
v2[2]=rz;
v3[0]=rx+1.0;
v3[1]=height_field[rz+1][rx+1];
v3[2]=rz+1.0;

return getHeight(v2,v1,v3,x,z);
}
else
{
v1[0]=rx;
v1[1]=height_field[rz+1][rx];
v1[2]=rz+1.0;
v2[0]=rx+1;
v2[1]=height_field[rz+1][rx+1];
v2[2]=rz+1.0;
v3[0]=rx+1.0;
v3[1]=height_field[rz][rx+1];
v3[2]=rz;

return getHeight(v1,v3,v2,x,z);
}
}
return -1.0f;
}





[ IcarusIndie.com | recycledrussianbrides.com | Got Linux? ]


Will Post For Food

Share this post


Link to post
Share on other sites