Buckets:
ktongue/docker_container / simsite /frontend /node_modules /three /src /geometries /CylinderGeometry.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 CylinderGeometry extends BufferGeometry { | |
| constructor( radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) { | |
| super(); | |
| this.type = 'CylinderGeometry'; | |
| this.parameters = { | |
| radiusTop: radiusTop, | |
| radiusBottom: radiusBottom, | |
| height: height, | |
| radialSegments: radialSegments, | |
| heightSegments: heightSegments, | |
| openEnded: openEnded, | |
| thetaStart: thetaStart, | |
| thetaLength: thetaLength | |
| }; | |
| const scope = this; | |
| radialSegments = Math.floor( radialSegments ); | |
| heightSegments = Math.floor( heightSegments ); | |
| // buffers | |
| const indices = []; | |
| const vertices = []; | |
| const normals = []; | |
| const uvs = []; | |
| // helper variables | |
| let index = 0; | |
| const indexArray = []; | |
| const halfHeight = height / 2; | |
| let groupStart = 0; | |
| // generate geometry | |
| generateTorso(); | |
| if ( openEnded === false ) { | |
| if ( radiusTop > 0 ) generateCap( true ); | |
| if ( radiusBottom > 0 ) generateCap( false ); | |
| } | |
| // build geometry | |
| this.setIndex( indices ); | |
| this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); | |
| this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); | |
| this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); | |
| function generateTorso() { | |
| const normal = new Vector3(); | |
| const vertex = new Vector3(); | |
| let groupCount = 0; | |
| // this will be used to calculate the normal | |
| const slope = ( radiusBottom - radiusTop ) / height; | |
| // generate vertices, normals and uvs | |
| for ( let y = 0; y <= heightSegments; y ++ ) { | |
| const indexRow = []; | |
| const v = y / heightSegments; | |
| // calculate the radius of the current row | |
| const radius = v * ( radiusBottom - radiusTop ) + radiusTop; | |
| for ( let x = 0; x <= radialSegments; x ++ ) { | |
| const u = x / radialSegments; | |
| const theta = u * thetaLength + thetaStart; | |
| const sinTheta = Math.sin( theta ); | |
| const cosTheta = Math.cos( theta ); | |
| // vertex | |
| vertex.x = radius * sinTheta; | |
| vertex.y = - v * height + halfHeight; | |
| vertex.z = radius * cosTheta; | |
| vertices.push( vertex.x, vertex.y, vertex.z ); | |
| // normal | |
| normal.set( sinTheta, slope, cosTheta ).normalize(); | |
| normals.push( normal.x, normal.y, normal.z ); | |
| // uv | |
| uvs.push( u, 1 - v ); | |
| // save index of vertex in respective row | |
| indexRow.push( index ++ ); | |
| } | |
| // now save vertices of the row in our index array | |
| indexArray.push( indexRow ); | |
| } | |
| // generate indices | |
| for ( let x = 0; x < radialSegments; x ++ ) { | |
| for ( let y = 0; y < heightSegments; y ++ ) { | |
| // we use the index array to access the correct indices | |
| const a = indexArray[ y ][ x ]; | |
| const b = indexArray[ y + 1 ][ x ]; | |
| const c = indexArray[ y + 1 ][ x + 1 ]; | |
| const d = indexArray[ y ][ x + 1 ]; | |
| // faces | |
| indices.push( a, b, d ); | |
| indices.push( b, c, d ); | |
| // update group counter | |
| groupCount += 6; | |
| } | |
| } | |
| // add a group to the geometry. this will ensure multi material support | |
| scope.addGroup( groupStart, groupCount, 0 ); | |
| // calculate new start value for groups | |
| groupStart += groupCount; | |
| } | |
| function generateCap( top ) { | |
| // save the index of the first center vertex | |
| const centerIndexStart = index; | |
| const uv = new Vector2(); | |
| const vertex = new Vector3(); | |
| let groupCount = 0; | |
| const radius = ( top === true ) ? radiusTop : radiusBottom; | |
| const sign = ( top === true ) ? 1 : - 1; | |
| // first we generate the center vertex data of the cap. | |
| // because the geometry needs one set of uvs per face, | |
| // we must generate a center vertex per face/segment | |
| for ( let x = 1; x <= radialSegments; x ++ ) { | |
| // vertex | |
| vertices.push( 0, halfHeight * sign, 0 ); | |
| // normal | |
| normals.push( 0, sign, 0 ); | |
| // uv | |
| uvs.push( 0.5, 0.5 ); | |
| // increase index | |
| index ++; | |
| } | |
| // save the index of the last center vertex | |
| const centerIndexEnd = index; | |
| // now we generate the surrounding vertices, normals and uvs | |
| for ( let x = 0; x <= radialSegments; x ++ ) { | |
| const u = x / radialSegments; | |
| const theta = u * thetaLength + thetaStart; | |
| const cosTheta = Math.cos( theta ); | |
| const sinTheta = Math.sin( theta ); | |
| // vertex | |
| vertex.x = radius * sinTheta; | |
| vertex.y = halfHeight * sign; | |
| vertex.z = radius * cosTheta; | |
| vertices.push( vertex.x, vertex.y, vertex.z ); | |
| // normal | |
| normals.push( 0, sign, 0 ); | |
| // uv | |
| uv.x = ( cosTheta * 0.5 ) + 0.5; | |
| uv.y = ( sinTheta * 0.5 * sign ) + 0.5; | |
| uvs.push( uv.x, uv.y ); | |
| // increase index | |
| index ++; | |
| } | |
| // generate indices | |
| for ( let x = 0; x < radialSegments; x ++ ) { | |
| const c = centerIndexStart + x; | |
| const i = centerIndexEnd + x; | |
| if ( top === true ) { | |
| // face top | |
| indices.push( i, i + 1, c ); | |
| } else { | |
| // face bottom | |
| indices.push( i + 1, i, c ); | |
| } | |
| groupCount += 3; | |
| } | |
| // add a group to the geometry. this will ensure multi material support | |
| scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 ); | |
| // calculate new start value for groups | |
| groupStart += groupCount; | |
| } | |
| } | |
| copy( source ) { | |
| super.copy( source ); | |
| this.parameters = Object.assign( {}, source.parameters ); | |
| return this; | |
| } | |
| static fromJSON( data ) { | |
| return new CylinderGeometry( data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength ); | |
| } | |
| } | |
| export { CylinderGeometry }; | |
Xet Storage Details
- Size:
- 5.87 kB
- Xet hash:
- d1d4e7510da0030aa77c2bd13f6154d6c2edd08a2481f741f6d58e1f9a77a10f
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.