| |
| |
| |
| |
|
|
| import { Geometry } from '../core/Geometry.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'; |
|
|
| |
|
|
| function CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { |
|
|
| Geometry.call( this ); |
|
|
| this.type = 'CylinderGeometry'; |
|
|
| this.parameters = { |
| radiusTop: radiusTop, |
| radiusBottom: radiusBottom, |
| height: height, |
| radialSegments: radialSegments, |
| heightSegments: heightSegments, |
| openEnded: openEnded, |
| thetaStart: thetaStart, |
| thetaLength: thetaLength |
| }; |
|
|
| this.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) ); |
| this.mergeVertices(); |
|
|
| } |
|
|
| CylinderGeometry.prototype = Object.create( Geometry.prototype ); |
| CylinderGeometry.prototype.constructor = CylinderGeometry; |
|
|
| |
|
|
| function CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { |
|
|
| BufferGeometry.call( this ); |
|
|
| this.type = 'CylinderBufferGeometry'; |
|
|
| this.parameters = { |
| radiusTop: radiusTop, |
| radiusBottom: radiusBottom, |
| height: height, |
| radialSegments: radialSegments, |
| heightSegments: heightSegments, |
| openEnded: openEnded, |
| thetaStart: thetaStart, |
| thetaLength: thetaLength |
| }; |
|
|
| var scope = this; |
|
|
| radiusTop = radiusTop !== undefined ? radiusTop : 1; |
| radiusBottom = radiusBottom !== undefined ? radiusBottom : 1; |
| height = height || 1; |
|
|
| radialSegments = Math.floor( radialSegments ) || 8; |
| heightSegments = Math.floor( heightSegments ) || 1; |
|
|
| openEnded = openEnded !== undefined ? openEnded : false; |
| thetaStart = thetaStart !== undefined ? thetaStart : 0.0; |
| thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; |
|
|
| |
|
|
| var indices = []; |
| var vertices = []; |
| var normals = []; |
| var uvs = []; |
|
|
| |
|
|
| var index = 0; |
| var indexArray = []; |
| var halfHeight = height / 2; |
| var groupStart = 0; |
|
|
| |
|
|
| generateTorso(); |
|
|
| if ( openEnded === false ) { |
|
|
| if ( radiusTop > 0 ) generateCap( true ); |
| if ( radiusBottom > 0 ) generateCap( false ); |
|
|
| } |
|
|
| |
|
|
| this.setIndex( indices ); |
| this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); |
| this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); |
| this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); |
|
|
| function generateTorso() { |
|
|
| var x, y; |
| var normal = new Vector3(); |
| var vertex = new Vector3(); |
|
|
| var groupCount = 0; |
|
|
| |
| var slope = ( radiusBottom - radiusTop ) / height; |
|
|
| |
|
|
| for ( y = 0; y <= heightSegments; y ++ ) { |
|
|
| var indexRow = []; |
|
|
| var v = y / heightSegments; |
|
|
| |
|
|
| var radius = v * ( radiusBottom - radiusTop ) + radiusTop; |
|
|
| for ( x = 0; x <= radialSegments; x ++ ) { |
|
|
| var u = x / radialSegments; |
|
|
| var theta = u * thetaLength + thetaStart; |
|
|
| var sinTheta = Math.sin( theta ); |
| var cosTheta = Math.cos( theta ); |
|
|
| |
|
|
| vertex.x = radius * sinTheta; |
| vertex.y = - v * height + halfHeight; |
| vertex.z = radius * cosTheta; |
| vertices.push( vertex.x, vertex.y, vertex.z ); |
|
|
| |
|
|
| normal.set( sinTheta, slope, cosTheta ).normalize(); |
| normals.push( normal.x, normal.y, normal.z ); |
|
|
| |
|
|
| uvs.push( u, 1 - v ); |
|
|
| |
|
|
| indexRow.push( index ++ ); |
|
|
| } |
|
|
| |
|
|
| indexArray.push( indexRow ); |
|
|
| } |
|
|
| |
|
|
| for ( x = 0; x < radialSegments; x ++ ) { |
|
|
| for ( y = 0; y < heightSegments; y ++ ) { |
|
|
| |
|
|
| var a = indexArray[ y ][ x ]; |
| var b = indexArray[ y + 1 ][ x ]; |
| var c = indexArray[ y + 1 ][ x + 1 ]; |
| var d = indexArray[ y ][ x + 1 ]; |
|
|
| |
|
|
| indices.push( a, b, d ); |
| indices.push( b, c, d ); |
|
|
| |
|
|
| groupCount += 6; |
|
|
| } |
|
|
| } |
|
|
| |
|
|
| scope.addGroup( groupStart, groupCount, 0 ); |
|
|
| |
|
|
| groupStart += groupCount; |
|
|
| } |
|
|
| function generateCap( top ) { |
|
|
| var x, centerIndexStart, centerIndexEnd; |
|
|
| var uv = new Vector2(); |
| var vertex = new Vector3(); |
|
|
| var groupCount = 0; |
|
|
| var radius = ( top === true ) ? radiusTop : radiusBottom; |
| var sign = ( top === true ) ? 1 : - 1; |
|
|
| |
| centerIndexStart = index; |
|
|
| |
| |
| |
|
|
| for ( x = 1; x <= radialSegments; x ++ ) { |
|
|
| |
|
|
| vertices.push( 0, halfHeight * sign, 0 ); |
|
|
| |
|
|
| normals.push( 0, sign, 0 ); |
|
|
| |
|
|
| uvs.push( 0.5, 0.5 ); |
|
|
| |
|
|
| index ++; |
|
|
| } |
|
|
| |
|
|
| centerIndexEnd = index; |
|
|
| |
|
|
| for ( x = 0; x <= radialSegments; x ++ ) { |
|
|
| var u = x / radialSegments; |
| var theta = u * thetaLength + thetaStart; |
|
|
| var cosTheta = Math.cos( theta ); |
| var sinTheta = Math.sin( theta ); |
|
|
| |
|
|
| vertex.x = radius * sinTheta; |
| vertex.y = halfHeight * sign; |
| vertex.z = radius * cosTheta; |
| vertices.push( vertex.x, vertex.y, vertex.z ); |
|
|
| |
|
|
| normals.push( 0, sign, 0 ); |
|
|
| |
|
|
| uv.x = ( cosTheta * 0.5 ) + 0.5; |
| uv.y = ( sinTheta * 0.5 * sign ) + 0.5; |
| uvs.push( uv.x, uv.y ); |
|
|
| |
|
|
| index ++; |
|
|
| } |
|
|
| |
|
|
| for ( x = 0; x < radialSegments; x ++ ) { |
|
|
| var c = centerIndexStart + x; |
| var i = centerIndexEnd + x; |
|
|
| if ( top === true ) { |
|
|
| |
|
|
| indices.push( i, i + 1, c ); |
|
|
| } else { |
|
|
| |
|
|
| indices.push( i + 1, i, c ); |
|
|
| } |
|
|
| groupCount += 3; |
|
|
| } |
|
|
| |
|
|
| scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 ); |
|
|
| |
|
|
| groupStart += groupCount; |
|
|
| } |
|
|
| } |
|
|
| CylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); |
| CylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry; |
|
|
|
|
| export { CylinderGeometry, CylinderBufferGeometry }; |
|
|