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;
							 |