File: //var/www/aspa/three/geometries/PolyhedronGeometry.js
import { BufferGeometry } from '../core/BufferGeometry.js';
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
import { Vector3 } from '../math/Vector3.js';
import { Vector2 } from '../math/Vector2.js';
class PolyhedronGeometry extends BufferGeometry {
	constructor( vertices = [], indices = [], radius = 1, detail = 0 ) {
		super();
		this.type = 'PolyhedronGeometry';
		this.parameters = {
			vertices: vertices,
			indices: indices,
			radius: radius,
			detail: detail
		};
		// default buffer data
		const vertexBuffer = [];
		const uvBuffer = [];
		// the subdivision creates the vertex buffer data
		subdivide( detail );
		// all vertices should lie on a conceptual sphere with a given radius
		applyRadius( radius );
		// finally, create the uv data
		generateUVs();
		// build non-indexed geometry
		this.setAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );
		this.setAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );
		this.setAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );
		if ( detail === 0 ) {
			this.computeVertexNormals(); // flat normals
		} else {
			this.normalizeNormals(); // smooth normals
		}
		// helper functions
		function subdivide( detail ) {
			const a = new Vector3();
			const b = new Vector3();
			const c = new Vector3();
			// iterate over all faces and apply a subdivision with the given detail value
			for ( let i = 0; i < indices.length; i += 3 ) {
				// get the vertices of the face
				getVertexByIndex( indices[ i + 0 ], a );
				getVertexByIndex( indices[ i + 1 ], b );
				getVertexByIndex( indices[ i + 2 ], c );
				// perform subdivision
				subdivideFace( a, b, c, detail );
			}
		}
		function subdivideFace( a, b, c, detail ) {
			const cols = detail + 1;
			// we use this multidimensional array as a data structure for creating the subdivision
			const v = [];
			// construct all of the vertices for this subdivision
			for ( let i = 0; i <= cols; i ++ ) {
				v[ i ] = [];
				const aj = a.clone().lerp( c, i / cols );
				const bj = b.clone().lerp( c, i / cols );
				const rows = cols - i;
				for ( let j = 0; j <= rows; j ++ ) {
					if ( j === 0 && i === cols ) {
						v[ i ][ j ] = aj;
					} else {
						v[ i ][ j ] = aj.clone().lerp( bj, j / rows );
					}
				}
			}
			// construct all of the faces
			for ( let i = 0; i < cols; i ++ ) {
				for ( let j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {
					const k = Math.floor( j / 2 );
					if ( j % 2 === 0 ) {
						pushVertex( v[ i ][ k + 1 ] );
						pushVertex( v[ i + 1 ][ k ] );
						pushVertex( v[ i ][ k ] );
					} else {
						pushVertex( v[ i ][ k + 1 ] );
						pushVertex( v[ i + 1 ][ k + 1 ] );
						pushVertex( v[ i + 1 ][ k ] );
					}
				}
			}
		}
		function applyRadius( radius ) {
			const vertex = new Vector3();
			// iterate over the entire buffer and apply the radius to each vertex
			for ( let i = 0; i < vertexBuffer.length; i += 3 ) {
				vertex.x = vertexBuffer[ i + 0 ];
				vertex.y = vertexBuffer[ i + 1 ];
				vertex.z = vertexBuffer[ i + 2 ];
				vertex.normalize().multiplyScalar( radius );
				vertexBuffer[ i + 0 ] = vertex.x;
				vertexBuffer[ i + 1 ] = vertex.y;
				vertexBuffer[ i + 2 ] = vertex.z;
			}
		}
		function generateUVs() {
			const vertex = new Vector3();
			for ( let i = 0; i < vertexBuffer.length; i += 3 ) {
				vertex.x = vertexBuffer[ i + 0 ];
				vertex.y = vertexBuffer[ i + 1 ];
				vertex.z = vertexBuffer[ i + 2 ];
				const u = azimuth( vertex ) / 2 / Math.PI + 0.5;
				const v = inclination( vertex ) / Math.PI + 0.5;
				uvBuffer.push( u, 1 - v );
			}
			correctUVs();
			correctSeam();
		}
		function correctSeam() {
			// handle case when face straddles the seam, see #3269
			for ( let i = 0; i < uvBuffer.length; i += 6 ) {
				// uv data of a single face
				const x0 = uvBuffer[ i + 0 ];
				const x1 = uvBuffer[ i + 2 ];
				const x2 = uvBuffer[ i + 4 ];
				const max = Math.max( x0, x1, x2 );
				const min = Math.min( x0, x1, x2 );
				// 0.9 is somewhat arbitrary
				if ( max > 0.9 && min < 0.1 ) {
					if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;
					if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;
					if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;
				}
			}
		}
		function pushVertex( vertex ) {
			vertexBuffer.push( vertex.x, vertex.y, vertex.z );
		}
		function getVertexByIndex( index, vertex ) {
			const stride = index * 3;
			vertex.x = vertices[ stride + 0 ];
			vertex.y = vertices[ stride + 1 ];
			vertex.z = vertices[ stride + 2 ];
		}
		function correctUVs() {
			const a = new Vector3();
			const b = new Vector3();
			const c = new Vector3();
			const centroid = new Vector3();
			const uvA = new Vector2();
			const uvB = new Vector2();
			const uvC = new Vector2();
			for ( let i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {
				a.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );
				b.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );
				c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );
				uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );
				uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );
				uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );
				centroid.copy( a ).add( b ).add( c ).divideScalar( 3 );
				const azi = azimuth( centroid );
				correctUV( uvA, j + 0, a, azi );
				correctUV( uvB, j + 2, b, azi );
				correctUV( uvC, j + 4, c, azi );
			}
		}
		function correctUV( uv, stride, vector, azimuth ) {
			if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {
				uvBuffer[ stride ] = uv.x - 1;
			}
			if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {
				uvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;
			}
		}
		// Angle around the Y axis, counter-clockwise when looking from above.
		function azimuth( vector ) {
			return Math.atan2( vector.z, - vector.x );
		}
		// Angle above the XZ plane.
		function inclination( vector ) {
			return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
		}
	}
	copy( source ) {
		super.copy( source );
		this.parameters = Object.assign( {}, source.parameters );
		return this;
	}
	static fromJSON( data ) {
		return new PolyhedronGeometry( data.vertices, data.indices, data.radius, data.details );
	}
}
export { PolyhedronGeometry };