Finding Z given X & Y coordinates on terrain?
Posted
by
mrky
on Game Development
See other posts from Game Development
or by mrky
Published on 2013-11-11T21:13:16Z
Indexed on
2013/11/11
22:16 UTC
Read the original article
Hit count: 361
I need to know what the most efficient way of finding Z given X & Y coordinates on terrain. My terrain is set up as a grid, each grid block consisting of two triangles, which may be flipped in any direction. I want to move game objects smoothly along the floor of the terrain without "stepping." I'm currently using the following method with unexpected results:
double mapClass::getZ(double x, double y)
{
int vertexIndex = ((floor(y))*width*2)+((floor(x))*2);
vec3ray ray = {glm::vec3(x, y, 2), glm::vec3(x, y, 0)};
vec3triangle tri1 = { glmFrom(vertices[vertexIndex].v1),
glmFrom(vertices[vertexIndex].v2),
glmFrom(vertices[vertexIndex].v3) };
vec3triangle tri2 = { glmFrom(vertices[vertexIndex+1].v1),
glmFrom(vertices[vertexIndex+1].v2),
glmFrom(vertices[vertexIndex+1].v3) };
glm::vec3 intersect;
if (!intersectRayTriangle(tri1, ray, intersect))
{
intersectRayTriangle(tri2, ray, intersect);
}
return intersect.z;
}
intersectRayTriangle()
and glmFrom()
are as follows:
bool intersectRayTriangle(vec3triangle tri, vec3ray ray, glm::vec3 &worldIntersect)
{
glm::vec3 barycentricIntersect;
if (glm::intersectLineTriangle(ray.origin, ray.direction, tri.p0, tri.p1, tri.p2, barycentricIntersect))
{
// Convert barycentric to world coordinates
double u, v, w;
u = barycentricIntersect.x;
v = barycentricIntersect.y;
w = 1 - (u+v);
worldIntersect.x = (u * tri.p0.x + v * tri.p1.x + w * tri.p2.x);
worldIntersect.y = (u * tri.p0.y + v * tri.p1.y + w * tri.p2.y);
worldIntersect.z = (u * tri.p0.z + v * tri.p1.z + w * tri.p2.z);
return true;
}
else
{
return false;
}
}
glm::vec3 glmFrom(s_point3f point)
{
return glm::vec3(point.x, point.y, point.z);
}
My convenience structures are defined as:
struct s_point3f { GLfloat x, y, z; };
struct s_triangle3f { s_point3f v1, v2, v3; };
struct vec3ray { glm::vec3 origin, direction; };
struct vec3triangle { glm::vec3 p0, p1, p2; };
vertices
is defined as:
std::vector<s_triangle3f> vertices;
Basically, I'm trying to get the intersect of a ray (which is positioned at the x, and y coordinates specified facing pointing downwards toward the terrain) and one of the two triangles on the grid. getZ()
rarely returns anything but 0. Other times, the numbers it generates seem to be completely off. Am I taking the wrong approach? Can anyone see a problem with my code? Any help or critique is appreciated!
© Game Development or respective owner