本文已抄送到天地会 : http://bbs.9ria.com/thread-192787-1-1.html
这是效果图
首先先准备一张高度图
你可以用Photoshop制作,在创建图片的时候就选择灰度图. 当你制作完毕一张灰度图的时候,保存的格式最好是8Bit的RAW文件,这样每个像素都被保存在 unsignedbyte 中,且没有各种烦人的文件头信息.有且只有像素信息.
为了方便测试,在AS中我们将这个RAW文件嵌入到项目中,用下面代码
[cc lang=”actionscript3″]
[Embed(source=”../../source/coastMountain64.raw”,mimeType = “application/octet-stream”)]
private var terrainData : Class;
[/cc]
当文件嵌入后,我们就开始着手解析了.解析的方法很简单,按顺序读取字节流,然后存进一个 Vector.
[cc lang=”actionscript3″]
private function parseHeightMaps(data : ByteArray) : Boolean
{
if(null == data || 0 == data.bytesAvailable) return false;
var len : uint = data.bytesAvailable;
for(var i : int = 0; i < len; i++){
m_heightMap.push(data.readUnsignedByte());
}
return true;
}
[/cc]
现在我们有了地形的数据了,为了让其显示出来,我们开始创建顶点和索引
顶点的格式是 [x,y,z,u,v] 5个数据
如果每个顶点之间是紧密排列的话,其中u,v的递增量可以通过下面的方式计算出.
[cc lang="actionscript3"]
var uCoordIncrementSize : Number = 1.0 / 每列顶点数;
var vCoordIncrementSize : Number = 1.0 / 每行顶点数;
[/cc]
由于高度图是 64 * 64 的大小,我们做 64 * 64的循环来取顶点
startZ = 0, endZ = 63;
startX = 0, endX = 63;
如果顶点间是紧密排列的. 那么 m_cellSpacing 为1.0
[cc lang="actionscript3"]
for(z = startZ; z >= endZ; z -= m_cellSpacing)
{
j = 0;
for(x = startX; x <= endX; x += m_cellSpacing)
{
//计算当前顶点缓冲的索引,避免死循环
var index : int = i * m_numVertsPerRow + j;
m_rawVertex.push(x,m_heightMap[index],z,j * uCoordIncrementSize,i * vCoordIncrementSize);
j++;
}
i++;
}
[/cc]
解析完顶点后,就要开始计算索引了.
通过这张图,可以理解到,2个三角形和顶点数组中索引对应的上下两行的关系.
当前顶点的 index, index + 1 和下一行的 index 构成第一个三角形, 另一半三角形也同样. 他们共用 C 顶点.
转换成代码就是如下的形式
[cc lang=”actionscript3″]
private function computeIndices() : void
{
var baseIndex : int = 0;
for(var i : int = 0; i < m_numCellsperCol; i++) { for(var j : int = 0; j < m_numCellsPerRow; j++) { m_rawIndex[baseIndex] = i * m_numVertsPerRow + j; m_rawIndex[baseIndex + 1] = i * m_numVertsPerRow + j + 1; m_rawIndex[baseIndex + 2] = (i + 1) * m_numVertsPerRow + j; m_rawIndex[baseIndex + 3] = (i + 1) * m_numVertsPerRow + j; m_rawIndex[baseIndex + 4] = i * m_numVertsPerRow + j + 1; m_rawIndex[baseIndex + 5] = (i + 1) * m_numVertsPerRow + j + 1; baseIndex += 6; } } trace("索引解析完毕"); } [/cc] 现在我们有了顶点,也有了索引.就可以将其显示出来了. 贴图什么随便设定就好了. demo is here
你可能会觉得地形很难看出高低的感觉,这是因为没有地形没有阴影,当然这是下一篇进阶的功能了.