/** * @author mr.doob / http://mrdoob.com/ */ THREE.CylinderGeometry = function ( radiusTop, radiusBottom, height, segmentsRadius, segmentsHeight, openEnded ) { THREE.Geometry.call( this ); radiusTop = radiusTop !== undefined ? radiusTop : 20; radiusBottom = radiusBottom !== undefined ? radiusBottom : 20; height = height !== undefined ? height : 100; var heightHalf = height / 2; var segmentsX = segmentsRadius || 8; var segmentsY = segmentsHeight || 1; var x, y, vertices = [], uvs = []; for ( y = 0; y <= segmentsY; y ++ ) { var verticesRow = []; var uvsRow = []; var v = y / segmentsY; var radius = v * ( radiusBottom - radiusTop ) + radiusTop; for ( x = 0; x <= segmentsX; x ++ ) { var u = x / segmentsX; var xpos = radius * Math.sin( u * Math.PI * 2 ); var ypos = - v * height + heightHalf; var zpos = radius * Math.cos( u * Math.PI * 2 ); this.vertices.push( new THREE.Vertex( new THREE.Vector3( xpos, ypos, zpos ) ) ); verticesRow.push( this.vertices.length - 1 ); uvsRow.push( new THREE.UV( u, v ) ); } vertices.push( verticesRow ); uvs.push( uvsRow ); } for ( y = 0; y < segmentsY; y ++ ) { for ( x = 0; x < segmentsX; x ++ ) { var v1 = vertices[ y ][ x ]; var v2 = vertices[ y + 1 ][ x ]; var v3 = vertices[ y + 1 ][ x + 1 ]; var v4 = vertices[ y ][ x + 1 ]; // FIXME: These normals aren't right for cones. var n1 = this.vertices[ v1 ].position.clone().setY( 0 ).normalize(); var n2 = this.vertices[ v2 ].position.clone().setY( 0 ).normalize(); var n3 = this.vertices[ v3 ].position.clone().setY( 0 ).normalize(); var n4 = this.vertices[ v4 ].position.clone().setY( 0 ).normalize(); var uv1 = uvs[ y ][ x ].clone(); var uv2 = uvs[ y + 1 ][ x ].clone(); var uv3 = uvs[ y + 1 ][ x + 1 ].clone(); var uv4 = uvs[ y ][ x + 1 ].clone(); this.faces.push( new THREE.Face4( v1, v2, v3, v4, [ n1, n2, n3, n4 ] ) ); this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3, uv4 ] ); } } // top cap if ( !openEnded && radiusTop > 0 ) { this.vertices.push( new THREE.Vertex( new THREE.Vector3( 0, heightHalf, 0 ) ) ); for ( x = 0; x < segmentsX; x ++ ) { var v1 = vertices[ 0 ][ x ]; var v2 = vertices[ 0 ][ x + 1 ]; var v3 = this.vertices.length - 1; var n1 = new THREE.Vector3( 0, 1, 0 ); var n2 = new THREE.Vector3( 0, 1, 0 ); var n3 = new THREE.Vector3( 0, 1, 0 ); var uv1 = uvs[ 0 ][ x ].clone(); var uv2 = uvs[ 0 ][ x + 1 ].clone(); var uv3 = new THREE.UV( uv2.u, 0 ); this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) ); this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] ); } } // bottom cap if ( !openEnded && radiusBottom > 0 ) { this.vertices.push( new THREE.Vertex( new THREE.Vector3( 0, - heightHalf, 0 ) ) ); for ( x = 0; x < segmentsX; x ++ ) { var v1 = vertices[ y ][ x + 1 ]; var v2 = vertices[ y ][ x ]; var v3 = this.vertices.length - 1; var n1 = new THREE.Vector3( 0, - 1, 0 ); var n2 = new THREE.Vector3( 0, - 1, 0 ); var n3 = new THREE.Vector3( 0, - 1, 0 ); var uv1 = uvs[ y ][ x + 1 ].clone(); var uv2 = uvs[ y ][ x ].clone(); var uv3 = new THREE.UV( uv2.u, 1 ); this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) ); this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] ); } } this.computeCentroids(); this.computeFaceNormals(); } THREE.CylinderGeometry.prototype = new THREE.Geometry(); THREE.CylinderGeometry.prototype.constructor = THREE.CylinderGeometry;