CSharpGL.SphereModel.SphereModel C# (CSharp) Метод

SphereModel() приватный Метод

private SphereModel ( float radius = 1.0f, int latitudeParts = 10, int longitudeParts = 40 ) : System
radius float
latitudeParts int 用纬线把地球切割为几块。
longitudeParts int 用经线把地球切割为几块。
Результат System
        internal SphereModel(float radius = 1.0f, int latitudeParts = 10, int longitudeParts = 40)
        {
            if (radius <= 0.0f || latitudeParts < 2 || longitudeParts < 3) { throw new Exception(); }

            int vertexCount = (latitudeParts + 1) * (longitudeParts + 1);
            this.positions = new vec3[vertexCount];
            this.normals = new vec3[vertexCount];
            this.colors = new vec3[vertexCount];
            this.uv = new vec2[vertexCount];

            int indexCount = (latitudeParts) * (2 * (longitudeParts + 1) + 1);
            this.indexes = new uint[indexCount];

            int index = 0;

            //// 把星球平铺在一个平面上
            //for (int i = 0; i < latitudeParts + 1; i++)
            //{
            //    double theta = (latitudeParts - i * 2) * Math.PI / 2 / latitudeParts;
            //    double y = radius * Math.Sin(theta);
            //    for (int j = 0; j < longitudeParts + 1; j++)
            //    {
            //        double x = radius * (i - latitudeParts / 2);
            //        double z = radius * (j - longitudeParts / 2);

            //        vec3 position = new vec3((float)x, (float)y, (float)z);
            //        this.positions[index] = position;

            //        this.normals[index] = position.normalize();

            //        this.colors[index] = colorGenerator(i, j);

            //        index++;
            //    }
            //}

            for (int i = 0; i < latitudeParts + 1; i++)
            {
                double theta = (latitudeParts - i * 2) * Math.PI / 2 / latitudeParts;
                double y = radius * Math.Sin(theta);
                for (int j = 0; j < longitudeParts + 1; j++)
                {
                    double x = radius * Math.Cos(theta) * Math.Sin(j * Math.PI * 2 / longitudeParts);
                    double z = radius * Math.Cos(theta) * Math.Cos(j * Math.PI * 2 / longitudeParts);

                    vec3 position = new vec3((float)x, (float)y, (float)z);
                    this.positions[index] = position;

                    this.normals[index] = position.normalize();

                    vec3 color = position.normalize();
                    if (color.x < 0) { color.x = -(color.x / 2); }
                    if (color.y < 0) { color.y = -(color.y / 2); }
                    if (color.z < 0) { color.z = -(color.z / 2); }
                    this.colors[index] = color;
                    this.uv[index] = new vec2((float)j / (float)longitudeParts, (float)i / (float)latitudeParts);

                    index++;
                }
            }

            // 索引
            index = 0;
            for (int i = 0; i < latitudeParts; i++)
            {
                for (int j = 0; j < longitudeParts + 1; j++)
                {
                    this.indexes[index++] = (uint)((longitudeParts + 1) * (i + 0) + j);
                    this.indexes[index++] = (uint)((longitudeParts + 1) * (i + 1) + j);
                }
                // use
                // GL.Enable(GL.GL_PRIMITIVE_RESTART);
                // GL.PrimitiveRestartIndex(uint.MaxValue);
                // GL.Disable(GL.GL_PRIMITIVE_RESTART);
                this.indexes[index++] = uint.MaxValue;
            }
        }