Пример #1
0
        //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));
        }
Пример #2
0
        //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);
        }
Пример #3
0
        /// <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);
        }