//public SharedBlockIndexData GetSharedIndexData(int terrEdgeSize) //{ // SharedBlockIndexData result; // if (!sharedIBCache.TryGetValue(terrEdgeSize, out result )) // { // result = new SharedBlockIndexData(renderSystem, terrEdgeSize); // sharedIBCache.Add(terrEdgeSize, result); // } // return result; //} /// <summary> /// Create a terrain mesh at the given tile-based coordinate and with a given size. /// </summary> /// <param name="rs"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="size">The size can be either 33 or 17</param> /// <returns></returns> public ResourceHandle <TerrainMesh> CreateInstance(RenderSystem rs, int x, int y, int size) { if (!loaded) { lock (syncHelper) { if (!loaded) { loaded = true; renderSystem = rs; index33 = new SharedIndexData(rs, 33); index17 = new SharedIndexData(rs, 17); //SharedBlockIndexData sharedIdxBuffer1025 = new SharedBlockIndexData(rs, 513); //SharedBlockIndexData sharedIdxBuffer257 = new SharedBlockIndexData(rs, 129); //SharedBlockIndexData sharedIdxBuffer65 = new SharedBlockIndexData(rs, 33); //sharedIBCache.Add(513, sharedIdxBuffer1025); //sharedIBCache.Add(129, sharedIdxBuffer257); //sharedIBCache.Add(33, sharedIdxBuffer65); } } } Resource retrived = base.Exists(TerrainMesh.GetHashString(x, y, size)); if (retrived == null) { TerrainMesh mdl = new TerrainMesh(rs, x, y, size); retrived = mdl; base.NotifyResourceNew(mdl); } //else //{ // retrived.Use(); //} return(new ResourceHandle <TerrainMesh>((TerrainMesh)retrived)); }
//public SharedBlockIndexData GetSharedIndexData(int terrEdgeSize) //{ // SharedBlockIndexData result; // if (!sharedIBCache.TryGetValue(terrEdgeSize, out result )) // { // result = new SharedBlockIndexData(renderSystem, terrEdgeSize); // sharedIBCache.Add(terrEdgeSize, result); // } // return result; //} /// <summary> /// Create a terrain mesh at the given tile-based coordinate and with a given size. /// </summary> /// <param name="rs"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="size">The size can be either 33 or 17</param> /// <returns></returns> public ResourceHandle<TerrainMesh> CreateInstance(RenderSystem rs, int x, int y, int size) { if (!loaded) { lock (syncHelper) { if (!loaded) { loaded = true; renderSystem = rs; index33 = new SharedIndexData(rs, 33); index17 = new SharedIndexData(rs, 17); //SharedBlockIndexData sharedIdxBuffer1025 = new SharedBlockIndexData(rs, 513); //SharedBlockIndexData sharedIdxBuffer257 = new SharedBlockIndexData(rs, 129); //SharedBlockIndexData sharedIdxBuffer65 = new SharedBlockIndexData(rs, 33); //sharedIBCache.Add(513, sharedIdxBuffer1025); //sharedIBCache.Add(129, sharedIdxBuffer257); //sharedIBCache.Add(33, sharedIdxBuffer65); } } } Resource retrived = base.Exists(TerrainMesh.GetHashString(x, y, size)); if (retrived == null) { TerrainMesh mdl = new TerrainMesh(rs, x, y, size); retrived = mdl; base.NotifyResourceNew(mdl); } //else //{ // retrived.Use(); //} return new ResourceHandle<TerrainMesh>((TerrainMesh)retrived); }
/// <summary> /// This implements the method in resource, to load the mesh data(vertex buffer, index buffer) /// of this terrain tile. /// </summary> protected override void load() { // 读取地形数据 // This line will load the terrain data in this tile. float[] data = TerrainData.Instance.GetData(tileX, tileY, terrEdgeSize); float radtc = MathEx.Degree2Radian(tileCol); float radtl = MathEx.Degree2Radian(tileLat); float radSpan = MathEx.Degree2Radian(10); int vertexCount = terrEdgeSize * terrEdgeSize; int terrEdgeLen = terrEdgeSize - 1; if (terrEdgeSize == 33) { material.SetEffect(EffectManager.Instance.GetModelEffect(TerrainEffect33Factory.Name)); } else { material.SetEffect(EffectManager.Instance.GetModelEffect(TerrainEffect17Factory.Name)); } #region 顶点数据 vtxDecl = factory.CreateVertexDeclaration(TerrainVertex.Elements); vtxBuffer = factory.CreateVertexBuffer(vertexCount, vtxDecl, BufferUsage.WriteOnly); TerrainVertex[] vtxArray = new TerrainVertex[vertexCount]; float cellAngle = radSpan / (float)terrEdgeLen; #region 计算顶点坐标 // Caluclate the position of each vertex // i为纬度方向 // i is in the latitude direction for (int i = 0; i < terrEdgeSize; i++) { // j为经度方向 // j is in the longitude direction for (int j = 0; j < terrEdgeSize; j++) { Vector3 pos = PlanetEarth.GetPosition(radtc + j * cellAngle, radtl - i * cellAngle); int index = i * terrEdgeSize + j; // 计算海拔高度 // calculate the elevation float height = (data[index] - TerrainMeshManager.PostZeroLevel) * TerrainMeshManager.PostHeightScale; //if (height > 0) //{ // height = (height - 0) * TerrainMeshManager.PostHeightScale; //} //else //{ // height *= TerrainMeshManager.PostHeightScale; // height -= 10; // //if (height < -30) // // height = -30; //} Vector3 normal = pos; normal.Normalize(); vtxArray[index].Position = pos + normal * height; // this index is used to generate detailed texture coordinate in vertex shader vtxArray[index].Index = index; // map the texture coordinate for global texturing float curCol = radtc + j * cellAngle; float curLat = radSpan + radtl - i * cellAngle; curCol += MathEx.PIf; curLat -= MathEx.Degree2Radian(10); vtxArray[index].u = 0.5f * curCol / MathEx.PIf; vtxArray[index].v = (-curLat + MathEx.PiOver2) / MathEx.PIf; } } #endregion #endregion #region 索引数据 SharedIndexData sindexData = TerrainMeshManager.Instance.GetIndexData(terrEdgeSize); indexBuffer = sindexData.Index; #endregion #region 构造GeomentryData defGeometryData = new GeomentryData(); defGeometryData.VertexDeclaration = vtxDecl; defGeometryData.VertexSize = TerrainVertex.Size; defGeometryData.VertexBuffer = vtxBuffer; defGeometryData.IndexBuffer = indexBuffer; defGeometryData.PrimCount = indexBuffer.IndexCount / 3; defGeometryData.VertexCount = terrEdgeSize * terrEdgeSize; defGeometryData.PrimitiveType = RenderPrimitiveType.TriangleList; defGeometryData.BaseVertex = 0; #endregion vtxBuffer.SetData <TerrainVertex>(vtxArray); }