添加关照、全局等高线、修改图层问题
This commit is contained in:
		
							
								
								
									
										155
									
								
								static/sdk/three/jsm/geometries/RoundedBoxGeometry.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								static/sdk/three/jsm/geometries/RoundedBoxGeometry.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,155 @@ | ||||
| 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 ); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| class RoundedBoxGeometry extends BoxGeometry { | ||||
|  | ||||
| 	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 }; | ||||
		Reference in New Issue
	
	Block a user