Spaces:
Running
Running
/** | |
* @author zz85 / https://github.com/zz85 | |
* @author bhouston / http://clara.io | |
* @author Mugen87 / https://github.com/Mugen87 | |
*/ | |
import { Geometry } from '../core/Geometry.js'; | |
import { Float32BufferAttribute } from '../core/BufferAttribute.js'; | |
import { BufferGeometry } from '../core/BufferGeometry.js'; | |
import { Vector3 } from '../math/Vector3.js'; | |
import { Vector2 } from '../math/Vector2.js'; | |
import { _Math } from '../math/Math.js'; | |
// LatheGeometry | |
function LatheGeometry( points, segments, phiStart, phiLength ) { | |
Geometry.call( this ); | |
this.type = 'LatheGeometry'; | |
this.parameters = { | |
points: points, | |
segments: segments, | |
phiStart: phiStart, | |
phiLength: phiLength | |
}; | |
this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) ); | |
this.mergeVertices(); | |
} | |
LatheGeometry.prototype = Object.create( Geometry.prototype ); | |
LatheGeometry.prototype.constructor = LatheGeometry; | |
// LatheBufferGeometry | |
function LatheBufferGeometry( points, segments, phiStart, phiLength ) { | |
BufferGeometry.call( this ); | |
this.type = 'LatheBufferGeometry'; | |
this.parameters = { | |
points: points, | |
segments: segments, | |
phiStart: phiStart, | |
phiLength: phiLength | |
}; | |
segments = Math.floor( segments ) || 12; | |
phiStart = phiStart || 0; | |
phiLength = phiLength || Math.PI * 2; | |
// clamp phiLength so it's in range of [ 0, 2PI ] | |
phiLength = _Math.clamp( phiLength, 0, Math.PI * 2 ); | |
// buffers | |
var indices = []; | |
var vertices = []; | |
var uvs = []; | |
// helper variables | |
var base; | |
var inverseSegments = 1.0 / segments; | |
var vertex = new Vector3(); | |
var uv = new Vector2(); | |
var i, j; | |
// generate vertices and uvs | |
for ( i = 0; i <= segments; i ++ ) { | |
var phi = phiStart + i * inverseSegments * phiLength; | |
var sin = Math.sin( phi ); | |
var cos = Math.cos( phi ); | |
for ( j = 0; j <= ( points.length - 1 ); j ++ ) { | |
// vertex | |
vertex.x = points[ j ].x * sin; | |
vertex.y = points[ j ].y; | |
vertex.z = points[ j ].x * cos; | |
vertices.push( vertex.x, vertex.y, vertex.z ); | |
// uv | |
uv.x = i / segments; | |
uv.y = j / ( points.length - 1 ); | |
uvs.push( uv.x, uv.y ); | |
} | |
} | |
// indices | |
for ( i = 0; i < segments; i ++ ) { | |
for ( j = 0; j < ( points.length - 1 ); j ++ ) { | |
base = j + i * points.length; | |
var a = base; | |
var b = base + points.length; | |
var c = base + points.length + 1; | |
var d = base + 1; | |
// faces | |
indices.push( a, b, d ); | |
indices.push( b, c, d ); | |
} | |
} | |
// build geometry | |
this.setIndex( indices ); | |
this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); | |
this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); | |
// generate normals | |
this.computeVertexNormals(); | |
// if the geometry is closed, we need to average the normals along the seam. | |
// because the corresponding vertices are identical (but still have different UVs). | |
if ( phiLength === Math.PI * 2 ) { | |
var normals = this.attributes.normal.array; | |
var n1 = new Vector3(); | |
var n2 = new Vector3(); | |
var n = new Vector3(); | |
// this is the buffer offset for the last line of vertices | |
base = segments * points.length * 3; | |
for ( i = 0, j = 0; i < points.length; i ++, j += 3 ) { | |
// select the normal of the vertex in the first line | |
n1.x = normals[ j + 0 ]; | |
n1.y = normals[ j + 1 ]; | |
n1.z = normals[ j + 2 ]; | |
// select the normal of the vertex in the last line | |
n2.x = normals[ base + j + 0 ]; | |
n2.y = normals[ base + j + 1 ]; | |
n2.z = normals[ base + j + 2 ]; | |
// average normals | |
n.addVectors( n1, n2 ).normalize(); | |
// assign the new values to both normals | |
normals[ j + 0 ] = normals[ base + j + 0 ] = n.x; | |
normals[ j + 1 ] = normals[ base + j + 1 ] = n.y; | |
normals[ j + 2 ] = normals[ base + j + 2 ] = n.z; | |
} | |
} | |
} | |
LatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); | |
LatheBufferGeometry.prototype.constructor = LatheBufferGeometry; | |
export { LatheGeometry, LatheBufferGeometry }; | |