今天用到了通过射线检测地形三角形,获得某一点的精确高度,下面这个方法是OK的
使用方法:
- private void tst()
- {
- float y = 10;
- float x = 10;
- Vector3 v0 = new Vector3(-x, y, -x);
- Vector3 v1 = new Vector3(x, y, -x);
- Vector3 v2 = new Vector3(0, y, x);
- Ray r = new Ray();
- r.Position = new Vector3(0, 1000, 0);
- r.Direction = new Vector3(0, -1.0f, 0);
- float t = 0.0f;
- //如果正常工作的话,返回t=990
- I3DGraphicsHelper.RayTriangleIntersect(r, v0, v1, v2, out t);
- }
- // triangle intersect from //http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
- /// <summary>
- /// 返回射线和三角形是否相交
- /// 如果相交,out float t值就是射线的原点到三角形的距离
- /// </summary>
- /// <param name="r">射线</param>
- /// <param name="vert0">三角形顶点0</param>
- /// <param name="vert1">三角形顶点1</param>
- /// <param name="vert2">三角形顶点2</param>
- /// <param name="t">返回射线原点到三角形的距离</param>
- /// <returns></returns>
- public static bool RayTriangleIntersect(Ray r,
- Vector3 vert0, Vector3 vert1, Vector3 vert2,
- out float t)
- {
- t = 0;
- Vector3 edge1 = vert1 - vert0;
- Vector3 edge2 = vert2 - vert0;
- Vector3 tvec, pvec, qvec;
- float det, inv_det;
- pvec = Vector3.Cross(r.Direction, edge2);
- det = Vector3.Dot(edge1, pvec);
- if (det > -0.00001f)
- return false;
- inv_det = 1.0f / det;
- tvec = r.Position - vert0;
- float u = Vector3.Dot(tvec, pvec) * inv_det;
- if (u < -0.001f || u > 1.001f)
- return false;
- qvec = Vector3.Cross(tvec, edge1);
- float v = Vector3.Dot(r.Direction, qvec) * inv_det;
- if (v < -0.001f || u + v > 1.001f)
- return false;
- t = Vector3.Dot(edge2, qvec) * inv_det;
- if (t <= 0)
- return false;
- return true;
- }