地形高度算法小结
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://xiaoxiang.blog.51cto.com/88051/21443 |
地形一般是用网格再从高度图里读取每个顶点的高度来生成。若进一步,想实现摄像机在地形上行走的效果,就需要算出地形上任意一点的高度。总结了3个方法:
一:
《Introduction to 3D Game Programming With Directx 9.0》这本书里介绍的,利用向量来算。
![]() float Terrain::GetHeight(float x, float z) { // Translate on xz-plane by the transformation that takes // the terrain START point to the origin. x = ((float)_width / 2.0f) + x; z = ((float)_depth / 2.0f) - z; // Scale down by the transformation that makes the
// cellspacing equal to one. This is given by // 1 / cellspacing since; cellspacing * 1 / cellspacing = 1. x /= (float)_CellSpacing; z /= (float)_CellSpacing; // From now on, we will interpret our positive z-axis as
// going in the 'down' direction, rather than the 'up' direction. // This allows to extract the row and column simply by 'flooring' // x and z: float col = ::floorf(x);
float row = ::floorf(z); // get the heights of the quad we're in:
// // A B // *---* // | / | // *---* // C D float A = GetHeightMapEntry(row, col);
float B = GetHeightMapEntry(row, col+1); float C = GetHeightMapEntry(row+1, col); float D = GetHeightMapEntry(row+1, col+1); //
// Find the triangle we are in: // // Translate by the transformation that takes the upper-left
// corner of the cell we are in to the origin. Recall that our // cellspacing was nomalized to 1. Thus we have a unit square // at the origin of our +x -> 'right' and +z -> 'down' system. float dx = x - col; float dz = z - row; // Note the below compuations of u and v are unneccessary, we really
// only need the height, but we compute the entire vector to emphasis // the books discussion. float height = 0.0f; if(dz < 1.0f - dx) // upper triangle ABC { float uy = B - A; // A->B float vy = C - A; // A->C // Linearly interpolate on each vector. The height is the vertex
// height the vectors u and v originate from {A}, plus the heights // found by interpolating on each vector u and v. height = A + Lerp(0.0f, uy, dx) + Lerp(0.0f, vy, dz); } else // lower triangle DCB { float uy = C - D; // D->C float vy = B - D; // D->B // Linearly interpolate on each vector. The height is the vertex
// height the vectors u and v originate from {D}, plus the heights // found by interpolating on each vector u and v. height = D + Lerp(0.0f, uy, 1.0f - dx) + Lerp(0.0f, vy, 1.0f - dz); } return height;
} 用到的2个函数
float Terrain::Lerp(float a, float b, float t) //一个插值函数
{ return (a - (a*t) + (b*t)); } int Terrain::GetHeightMapEntry(int row, int col) //读取高度函数
{ return _heightmap[row * _numVertsPerRow + col]; // 高度图数据存在_heightmap里 } 二:
先计算出摄像机所在三角形的平面方程,然后带入摄像机的X,Z坐标,即可得高度Y
具体实现过程见http://creatorchen1984.spaces.live.com/ 《获取地形上某一点高度》,写的十分详细
三:
网上找的一个方法
假设你的地形为terrain[][];用下面的函数求出地形上点(x,z);的y值,将人物的高度加上这个y值即可.
float GetHeight(GLfloat x, GLfloat z) { float h=0; float Xb,Yb; int Xa,Ya; Xa=(int)x; Ya=(int)z; Xb=x-Xa; Yb=z-Ya; float a=terrain[Xa][Ya].y; float b=terrain[Xa+1][Ya].y; float c=terrain[Xa][Ya+1].y; float d=terrain[Xa+1][Ya+1].y; h=(a*(1-Xb)+b*Xb)*(1-Yb)+(c*(1-Xb)+d*Xb)*Yb; return h; } 本文出自 “小祥” 博客,请务必保留此出处http://xiaoxiang.blog.51cto.com/88051/21443 本文出自 51CTO.COM技术博客 |



xfxsworld
博客统计信息
热门文章
最新评论
友情链接