예제 #1
0
        void generate(object ctx)
        {
            building = true;

            List<int> inds = new List<int>(Icosphere.Indicies);
            List<VertexPositionColorNormal> verts = new List<VertexPositionColorNormal>();
            for (int i = 0; i < Icosphere.Verticies.Length; i++) {
                verts.Add(new VertexPositionColorNormal(Icosphere.Verticies[i] / Icosphere.Verticies[i].Length(), Icosphere.Verticies[i], landColor));
            }

            IndexBuffer = new Dictionary<int, int[]>();
            IndexBuffer[0] = inds.ToArray();

            LODv = new List<int>();
            LODv.Add(verts.Count);

            int levels = (int)ctx;
            for (int l = 1; l < levels; l++) {
                List<int> newinds = new List<int>();

                for (int i = 0; i < inds.Count; i+=3) {
                    int i1 = inds[i], i2 = inds[i + 1], i3 = inds[i + 2];
                    Vector3 v1 = verts[i1].Position, v2 = verts[i2].Position, v3 = verts[i3].Position;
                    Vector3 v4 = (v1 + v3) / 2f;
                    Vector3 v5 = (v1 + v2) / 2f;
                    Vector3 v6 = (v3 + v2) / 2f;
                    v4.Normalize(); v5.Normalize(); v6.Normalize();

                    verts.Add(new VertexPositionColorNormal(v4, v4, landColor));
                    verts.Add(new VertexPositionColorNormal(v5, v5, landColor));
                    verts.Add(new VertexPositionColorNormal(v6, v6, landColor));

                    int i4 = verts.Count - 3;
                    int i5 = verts.Count - 2;
                    int i6 = verts.Count - 1;

                    newinds.AddRange(new int[] { i1, i5, i4 });
                    newinds.AddRange(new int[] { i4, i5, i6 });
                    newinds.AddRange(new int[] { i3, i4, i6 });
                    newinds.AddRange(new int[] { i6, i5, i2 });
                }
                inds = new List<int>(newinds);
                IndexBuffer[l] = inds.ToArray();
                LODv.Add(verts.Count);
            }

            VertexBuffer = verts.ToArray();
            if (HasWater)
                WaterVertexBuffer = new VertexPositionColorPolar[VertexBuffer.Length];
            if (HasAtmosphere)
                AtmosphereVertexBuffer = new VertexPositionColorNormal[VertexBuffer.Length];
            // set terrain heights
            for (int i = 0; i < VertexBuffer.Length; i++) {
                // water verts
                if (HasWater){
                    WaterVertexBuffer[i] = new VertexPositionColorPolar(VertexBuffer[i].Position, Vector2.Zero, waterColor);
                    WaterVertexBuffer[i].Polar.X = (float)Math.Asin(WaterVertexBuffer[i].Position.Z);
                    WaterVertexBuffer[i].Polar.Y = (float)Math.Atan2(WaterVertexBuffer[i].Position.Y, WaterVertexBuffer[i].Position.X);
                    WaterVertexBuffer[i].Position *= Radius;
                }
                // atmo verts
                if (HasAtmosphere) {
                    AtmosphereVertexBuffer[i] = new VertexPositionColorNormal(VertexBuffer[i].Position, VertexBuffer[i].Position, atmosphereColor);
                    AtmosphereVertexBuffer[i].Normal.Normalize();
                    AtmosphereVertexBuffer[i].Position *= AtmosphereHeight;
                }

                // land verts
                VertexBuffer[i].Color = landColor;
                float h = getHeight(VertexBuffer[i].Position);
                if (h <= Radius)
                    VertexBuffer[i].Color = oceanFloorColor;
                VertexBuffer[i].Position *= h;
                VertexBuffer[i].Normal = Vector3.Zero;
            }
            for (int i = 0; i < IndexBuffer[levels - 1].Length; i+=3) {
                int i1 = IndexBuffer[levels - 1][i];
                int i2 = IndexBuffer[levels - 1][i + 1];
                int i3 = IndexBuffer[levels - 1][i + 2];
                Vector3 norm = -Vector3.Cross(VertexBuffer[i1].Position - VertexBuffer[i2].Position, VertexBuffer[i1].Position - VertexBuffer[i3].Position);
                VertexBuffer[i1].Normal += norm;
                VertexBuffer[i2].Normal += norm;
                VertexBuffer[i3].Normal += norm;
            }
            for (int i = 0; i < VertexBuffer.Length; i++)
                VertexBuffer[i].Normal.Normalize();

            if (HasWater){
                waves[0] = new Wave(.5f, 2, Vector2.UnitX, 50, 1f);
                waves[1] = new Wave(.2f, 2, Vector2.UnitY, 50, .2f);
            }

            built = true;
            building = false;
        }