166 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			166 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | import { Matrix3, Plane, Vector4 } from 'three'; | ||
|  | 
 | ||
|  | const _plane = new Plane(); | ||
|  | const _viewNormalMatrix = new Matrix3(); | ||
|  | 
 | ||
|  | let _clippingContextVersion = 0; | ||
|  | 
 | ||
|  | class ClippingContext { | ||
|  | 
 | ||
|  | 	constructor() { | ||
|  | 
 | ||
|  | 		this.version = ++ _clippingContextVersion; | ||
|  | 
 | ||
|  | 		this.globalClippingCount = 0; | ||
|  | 
 | ||
|  | 		this.localClippingCount = 0; | ||
|  | 		this.localClippingEnabled = false; | ||
|  | 		this.localClipIntersection = false; | ||
|  | 
 | ||
|  | 		this.planes = []; | ||
|  | 
 | ||
|  | 		this.parentVersion = 0; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	projectPlanes( source, offset ) { | ||
|  | 
 | ||
|  | 		const l = source.length; | ||
|  | 		const planes = this.planes; | ||
|  | 
 | ||
|  | 		for ( let i = 0; i < l; i ++ ) { | ||
|  | 
 | ||
|  | 			_plane.copy( source[ i ] ).applyMatrix4( this.viewMatrix, _viewNormalMatrix ); | ||
|  | 
 | ||
|  | 			const v = planes[ offset + i ]; | ||
|  | 			const normal = _plane.normal; | ||
|  | 
 | ||
|  | 			v.x = - normal.x; | ||
|  | 			v.y = - normal.y; | ||
|  | 			v.z = - normal.z; | ||
|  | 			v.w = _plane.constant; | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	updateGlobal( renderer, camera ) { | ||
|  | 
 | ||
|  | 		const rendererClippingPlanes = renderer.clippingPlanes; | ||
|  | 		this.viewMatrix = camera.matrixWorldInverse; | ||
|  | 
 | ||
|  | 		_viewNormalMatrix.getNormalMatrix( this.viewMatrix ); | ||
|  | 
 | ||
|  | 		let update = false; | ||
|  | 
 | ||
|  | 		if ( Array.isArray( rendererClippingPlanes ) && rendererClippingPlanes.length !== 0 ) { | ||
|  | 
 | ||
|  | 			const l = rendererClippingPlanes.length; | ||
|  | 
 | ||
|  | 			if ( l !== this.globalClippingCount ) { | ||
|  | 
 | ||
|  | 				const planes = []; | ||
|  | 
 | ||
|  | 				for ( let i = 0; i < l; i ++ ) { | ||
|  | 
 | ||
|  | 					planes.push( new Vector4() ); | ||
|  | 
 | ||
|  | 				} | ||
|  | 
 | ||
|  | 				this.globalClippingCount = l; | ||
|  | 				this.planes = planes; | ||
|  | 
 | ||
|  | 				update = true; | ||
|  | 
 | ||
|  | 			} | ||
|  | 
 | ||
|  | 			this.projectPlanes( rendererClippingPlanes, 0 ); | ||
|  | 
 | ||
|  | 		} else if ( this.globalClippingCount !== 0 ) { | ||
|  | 
 | ||
|  | 			this.globalClippingCount = 0; | ||
|  | 			this.planes = []; | ||
|  | 			update = true; | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if ( renderer.localClippingEnabled !== this.localClippingEnabled ) { | ||
|  | 
 | ||
|  | 			this.localClippingEnabled = renderer.localClippingEnabled; | ||
|  | 			update = true; | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if ( update ) this.version = _clippingContextVersion ++; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	update( parent, material ) { | ||
|  | 
 | ||
|  | 		let update = false; | ||
|  | 
 | ||
|  | 		if ( this !== parent && parent.version !== this.parentVersion ) { | ||
|  | 
 | ||
|  | 			this.globalClippingCount = material.isShadowNodeMaterial ? 0 : parent.globalClippingCount; | ||
|  | 			this.localClippingEnabled = parent.localClippingEnabled; | ||
|  | 			this.planes = Array.from( parent.planes ); | ||
|  | 			this.parentVersion = parent.version; | ||
|  | 			this.viewMatrix = parent.viewMatrix; | ||
|  | 
 | ||
|  | 
 | ||
|  | 			update = true; | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if ( this.localClippingEnabled ) { | ||
|  | 
 | ||
|  | 			const localClippingPlanes = material.clippingPlanes; | ||
|  | 
 | ||
|  | 			if ( ( Array.isArray( localClippingPlanes ) && localClippingPlanes.length !== 0 ) ) { | ||
|  | 
 | ||
|  | 				const l = localClippingPlanes.length; | ||
|  | 				const planes = this.planes; | ||
|  | 				const offset = this.globalClippingCount; | ||
|  | 
 | ||
|  | 				if ( update || l !== this.localClippingCount ) { | ||
|  | 
 | ||
|  | 					planes.length = offset + l; | ||
|  | 
 | ||
|  | 					for ( let i = 0; i < l; i ++ ) { | ||
|  | 
 | ||
|  | 						planes[ offset + i ] = new Vector4(); | ||
|  | 
 | ||
|  | 					} | ||
|  | 
 | ||
|  | 					this.localClippingCount = l; | ||
|  | 					update = true; | ||
|  | 
 | ||
|  | 				} | ||
|  | 
 | ||
|  | 				this.projectPlanes( localClippingPlanes, offset ); | ||
|  | 
 | ||
|  | 
 | ||
|  | 			} else if ( this.localClippingCount !== 0 ) { | ||
|  | 
 | ||
|  | 				this.localClippingCount = 0; | ||
|  | 				update = true; | ||
|  | 
 | ||
|  | 			} | ||
|  | 
 | ||
|  | 			if ( this.localClipIntersection !== material.clipIntersection ) { | ||
|  | 
 | ||
|  | 				this.localClipIntersection = material.clipIntersection; | ||
|  | 				update = true; | ||
|  | 
 | ||
|  | 			} | ||
|  | 
 | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if ( update ) this.version = _clippingContextVersion ++; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | export default ClippingContext; |