Beispiel #1
0
        public Sphere(ESphere type, IModule module, Color[] colors, float diameter = 2048, int tessellation = 128) {

            Vertices = new List<VertexPositionNormalColor>();

            Indices = new List<short>();

            if (tessellation < 3 || tessellation > 128) {
                throw new ArgumentOutOfRangeException(nameof(tessellation));
            }

            var verticalSegments = tessellation;
            var horizontalSegments = tessellation * 2;

            var radius = diameter / 2;

            var noise = module.GetPlanet(horizontalSegments, verticalSegments);

            switch (type) {
                case ESphere.Terrain: {
                    #region Terrain Vertex

                    AddVertex(Vector3.Down * radius * (1.0f + (float)noise[0, 0]), Vector3.Down, Color.White);

                    for (var i = 0; i < verticalSegments - 1; i++) {
                        var latitude = ((i + 1) * MathHelper.Pi / verticalSegments) - MathHelper.PiOver2;

                        var dy = (float)Math.Sin(latitude);
                        var dxz = (float)Math.Cos(latitude);

                        for (var j = 0; j < horizontalSegments; j++) {
                            var longitude = j * MathHelper.TwoPi / horizontalSegments;

                            var dx = (float)Math.Cos(longitude) * dxz;
                            var dz = (float)Math.Sin(longitude) * dxz;

                            var normal = new Vector3(dx, dy, dz);

                            var value = 1.0f + (float)noise[j, i];

                            var color = colors.GetColorAt(value - 1.0f);

                            var v = value;

                            AddVertex(normal * radius * v, normal * v, color);
                        }
                    }

                    AddVertex(Vector3.Up * radius * (1.0f + (float)noise[horizontalSegments - 1, verticalSegments - 1]), Vector3.Up, Color.White);

                    #endregion
                    break;
                }
                case ESphere.Ocean: {
                    #region Ocean Vertex

                    AddVertex(Vector3.Down * radius, Vector3.Down, Color.White);

                    for (var i = 0; i < verticalSegments - 1; i++) {
                        var latitude = ((i + 1) * MathHelper.Pi / verticalSegments) - MathHelper.PiOver2;

                        var dy = (float)Math.Sin(latitude);
                        var dxz = (float)Math.Cos(latitude);

                        for (var j = 0; j < horizontalSegments; j++) {
                            var longitude = j * MathHelper.TwoPi / horizontalSegments;

                            var dx = (float)Math.Cos(longitude) * dxz;
                            var dz = (float)Math.Sin(longitude) * dxz;

                            var normal = new Vector3(dx, dy, dz);

                            AddVertex(normal * radius, normal, colors.GetColorAt(0.0d));
                        }
                    }

                    AddVertex(Vector3.Up * radius, Vector3.Up, Color.White);

                    #endregion
                    break;
                }
                case ESphere.Sky: {
                    #region Sky Vertex

                    AddVertex(Vector3.Down * radius, Vector3.Down, Color.White);

                    for (var i = 0; i < verticalSegments - 1; i++) {
                        var latitude = ((i + 1) * MathHelper.Pi / verticalSegments) - MathHelper.PiOver2;

                        var dy = (float)Math.Sin(latitude);
                        var dxz = (float)Math.Cos(latitude);

                        for (var j = 0; j < horizontalSegments; j++) {
                            var longitude = j * MathHelper.TwoPi / horizontalSegments;

                            var dx = (float)Math.Cos(longitude) * dxz;
                            var dz = (float)Math.Sin(longitude) * dxz;

                            var normal = new Vector3(dx, dy, dz);

                            var value = (float)noise[j, i];

                            var color = colors.GetColorAt(value);

                            AddVertex(normal * radius, normal, color);
                        }
                    }

                    AddVertex(Vector3.Up * radius, Vector3.Up, Color.White);

                    #endregion
                    break;
                }
                default: {
                    throw new InvalidEnumArgumentException(nameof(type));
                }
            }

            #region Index

            for (var i = 0; i < horizontalSegments; i++) {
                AddIndex(0);
                AddIndex(1 + (i + 1) % horizontalSegments);
                AddIndex(1 + i);
            }

            for (var i = 0; i < verticalSegments - 2; i++) {
                for (var j = 0; j < horizontalSegments; j++) {
                    var nextI = i + 1;
                    var nextJ = (j + 1) % horizontalSegments;

                    AddIndex(1 + i * horizontalSegments + j);
                    AddIndex(1 + i * horizontalSegments + nextJ);
                    AddIndex(1 + nextI * horizontalSegments + j);

                    AddIndex(1 + i * horizontalSegments + nextJ);
                    AddIndex(1 + nextI * horizontalSegments + nextJ);
                    AddIndex(1 + nextI * horizontalSegments + j);
                }
            }

            for (var i = 0; i < horizontalSegments; i++) {
                var currentVertex = Vertices.Count;
                AddIndex(currentVertex - 1);
                AddIndex(currentVertex - 2 - (i + 1) % horizontalSegments);
                AddIndex(currentVertex - 2 - i);
            }

            #endregion

            InitializePrimitive(Game.Instance.GraphicsDevice);

        }