Buckets:
| import { | |
| BoxGeometry, | |
| Vector3 | |
| } from 'three'; | |
| const _tempNormal = new Vector3(); | |
| function getUv( faceDirVector, normal, uvAxis, projectionAxis, radius, sideLength ) { | |
| const totArcLength = 2 * Math.PI * radius / 4; | |
| // length of the planes between the arcs on each axis | |
| const centerLength = Math.max( sideLength - 2 * radius, 0 ); | |
| const halfArc = Math.PI / 4; | |
| // Get the vector projected onto the Y plane | |
| _tempNormal.copy( normal ); | |
| _tempNormal[ projectionAxis ] = 0; | |
| _tempNormal.normalize(); | |
| // total amount of UV space alloted to a single arc | |
| const arcUvRatio = 0.5 * totArcLength / ( totArcLength + centerLength ); | |
| // the distance along one arc the point is at | |
| const arcAngleRatio = 1.0 - ( _tempNormal.angleTo( faceDirVector ) / halfArc ); | |
| if ( Math.sign( _tempNormal[ uvAxis ] ) === 1 ) { | |
| return arcAngleRatio * arcUvRatio; | |
| } else { | |
| // total amount of UV space alloted to the plane between the arcs | |
| const lenUv = centerLength / ( totArcLength + centerLength ); | |
| return lenUv + arcUvRatio + arcUvRatio * ( 1.0 - arcAngleRatio ); | |
| } | |
| } | |
| /** | |
| * A special type of box geometry with rounded corners and edges. | |
| * | |
| * ```js | |
| * const geometry = new THREE.RoundedBoxGeometry(); | |
| * const material = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ); | |
| * const cube = new THREE.Mesh( geometry, material ); | |
| * scene.add( cube ); | |
| * ``` | |
| * | |
| * @augments BoxGeometry | |
| * @three_import import { RoundedBoxGeometry } from 'three/addons/geometries/RoundedBoxGeometry.js'; | |
| */ | |
| class RoundedBoxGeometry extends BoxGeometry { | |
| /** | |
| * Constructs a new rounded box geometry. | |
| * | |
| * @param {number} [width=1] - The width. That is, the length of the edges parallel to the X axis. | |
| * @param {number} [height=1] - The height. That is, the length of the edges parallel to the Y axis. | |
| * @param {number} [depth=1] - The depth. That is, the length of the edges parallel to the Z axis. | |
| * @param {number} [segments=2] - Number of segmented that form the rounded corners. | |
| * @param {number} [radius=0.1] - The radius of the rounded corners. | |
| */ | |
| constructor( width = 1, height = 1, depth = 1, segments = 2, radius = 0.1 ) { | |
| // ensure segments is odd so we have a plane connecting the rounded corners | |
| segments = segments * 2 + 1; | |
| // ensure radius isn't bigger than shortest side | |
| radius = Math.min( width / 2, height / 2, depth / 2, radius ); | |
| super( 1, 1, 1, segments, segments, segments ); | |
| // if we just have one segment we're the same as a regular box | |
| if ( segments === 1 ) return; | |
| const geometry2 = this.toNonIndexed(); | |
| this.index = null; | |
| this.attributes.position = geometry2.attributes.position; | |
| this.attributes.normal = geometry2.attributes.normal; | |
| this.attributes.uv = geometry2.attributes.uv; | |
| // | |
| const position = new Vector3(); | |
| const normal = new Vector3(); | |
| const box = new Vector3( width, height, depth ).divideScalar( 2 ).subScalar( radius ); | |
| const positions = this.attributes.position.array; | |
| const normals = this.attributes.normal.array; | |
| const uvs = this.attributes.uv.array; | |
| const faceTris = positions.length / 6; | |
| const faceDirVector = new Vector3(); | |
| const halfSegmentSize = 0.5 / segments; | |
| for ( let i = 0, j = 0; i < positions.length; i += 3, j += 2 ) { | |
| position.fromArray( positions, i ); | |
| normal.copy( position ); | |
| normal.x -= Math.sign( normal.x ) * halfSegmentSize; | |
| normal.y -= Math.sign( normal.y ) * halfSegmentSize; | |
| normal.z -= Math.sign( normal.z ) * halfSegmentSize; | |
| normal.normalize(); | |
| positions[ i + 0 ] = box.x * Math.sign( position.x ) + normal.x * radius; | |
| positions[ i + 1 ] = box.y * Math.sign( position.y ) + normal.y * radius; | |
| positions[ i + 2 ] = box.z * Math.sign( position.z ) + normal.z * radius; | |
| normals[ i + 0 ] = normal.x; | |
| normals[ i + 1 ] = normal.y; | |
| normals[ i + 2 ] = normal.z; | |
| const side = Math.floor( i / faceTris ); | |
| switch ( side ) { | |
| case 0: // right | |
| // generate UVs along Z then Y | |
| faceDirVector.set( 1, 0, 0 ); | |
| uvs[ j + 0 ] = getUv( faceDirVector, normal, 'z', 'y', radius, depth ); | |
| uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height ); | |
| break; | |
| case 1: // left | |
| // generate UVs along Z then Y | |
| faceDirVector.set( - 1, 0, 0 ); | |
| uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'y', radius, depth ); | |
| uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height ); | |
| break; | |
| case 2: // top | |
| // generate UVs along X then Z | |
| faceDirVector.set( 0, 1, 0 ); | |
| uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width ); | |
| uvs[ j + 1 ] = getUv( faceDirVector, normal, 'z', 'x', radius, depth ); | |
| break; | |
| case 3: // bottom | |
| // generate UVs along X then Z | |
| faceDirVector.set( 0, - 1, 0 ); | |
| uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width ); | |
| uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'x', radius, depth ); | |
| break; | |
| case 4: // front | |
| // generate UVs along X then Y | |
| faceDirVector.set( 0, 0, 1 ); | |
| uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'y', radius, width ); | |
| uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'x', radius, height ); | |
| break; | |
| case 5: // back | |
| // generate UVs along X then Y | |
| faceDirVector.set( 0, 0, - 1 ); | |
| uvs[ j + 0 ] = getUv( faceDirVector, normal, 'x', 'y', radius, width ); | |
| uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'x', radius, height ); | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| export { RoundedBoxGeometry }; | |
Xet Storage Details
- Size:
- 5.57 kB
- Xet hash:
- 12a5c54b45870974f0f9dd98b90bd05872bd1a194b59798d1078e680bb63689b
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.