import { Geometry } from "../Geometry";
import { Vector3 } from "..";
import { Sphere } from "../math/Sphere";

/**
 * 球形几何
 * 直接参考three的计算方式
 */
export class SphereGeometry extends Geometry {
    constructor(
        radius: number = 1,
        widthSegments: number = 8,
        heightSegments: number = 6,
        phiStart: number = 0,
        phiLength: number = Math.PI * 2,
        thetaStart: number = 0,
        thetaLength: number = Math.PI,
    ) {
        //处理分段，必须正整数
        widthSegments = Math.max(3, Math.floor(widthSegments));
        heightSegments = Math.max(2, Math.floor(heightSegments));
        //计算所有顶点，及索引及法线
        var thetaEnd = thetaStart + thetaLength;

        var ix: number, iy: number;

        var index = 0;
        var grid = [];

        var vertex = new Vector3();
        var normal = new Vector3();

        // buffers
        var indices = [];
        var vertices = [];
        var normals = [];
        var uvs = [];

        // generate vertices, normals and uvs

        for (iy = 0; iy <= heightSegments; iy++) {

            var verticesRow = [];

            var v = iy / heightSegments;

            for (ix = 0; ix <= widthSegments; ix++) {

                var u = ix / widthSegments;

                // vertex

                vertex.x = - radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
                vertex.y = radius * Math.cos(thetaStart + v * thetaLength);
                vertex.z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);

                vertices.push(vertex.x, vertex.y, vertex.z);

                // normal
                normal.set(vertex.x, vertex.y, vertex.z).normalize();
                normals.push(normal.x, normal.y, normal.z);

                // uv
                // uvs.push(u, 1 - v);
                uvs.push(u, v);//2d里面颠倒过贴图的y轴（其实是矫正）。所以v统统不用1-

                verticesRow.push(index++);
            }

            grid.push(verticesRow);

        }

        // indices
        for (iy = 0; iy < heightSegments; iy++) {
            for (ix = 0; ix < widthSegments; ix++) {
                var a = grid[iy][ix + 1];
                var b = grid[iy][ix];
                var c = grid[iy + 1][ix];
                var d = grid[iy + 1][ix + 1];
                if (iy !== 0 || thetaStart > 0) indices.push(a, b, d);
                if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d);
            }
        }
        super(vertices, indices, normals, null, uvs);

        //直接计算包围球
        this.boundingSphere = new Sphere(
            new Vector3(),
            radius
        )
    }
}