Spaces:
Running
Running
| /** | |
| * @author tschw | |
| */ | |
| import { Matrix3 } from '../../math/Matrix3.js'; | |
| import { Plane } from '../../math/Plane.js'; | |
| function WebGLClipping() { | |
| var scope = this, | |
| globalState = null, | |
| numGlobalPlanes = 0, | |
| localClippingEnabled = false, | |
| renderingShadows = false, | |
| plane = new Plane(), | |
| viewNormalMatrix = new Matrix3(), | |
| uniform = { value: null, needsUpdate: false }; | |
| this.uniform = uniform; | |
| this.numPlanes = 0; | |
| this.numIntersection = 0; | |
| this.init = function ( planes, enableLocalClipping, camera ) { | |
| var enabled = | |
| planes.length !== 0 || | |
| enableLocalClipping || | |
| // enable state of previous frame - the clipping code has to | |
| // run another frame in order to reset the state: | |
| numGlobalPlanes !== 0 || | |
| localClippingEnabled; | |
| localClippingEnabled = enableLocalClipping; | |
| globalState = projectPlanes( planes, camera, 0 ); | |
| numGlobalPlanes = planes.length; | |
| return enabled; | |
| }; | |
| this.beginShadows = function () { | |
| renderingShadows = true; | |
| projectPlanes( null ); | |
| }; | |
| this.endShadows = function () { | |
| renderingShadows = false; | |
| resetGlobalState(); | |
| }; | |
| this.setState = function ( planes, clipIntersection, clipShadows, camera, cache, fromCache ) { | |
| if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) { | |
| // there's no local clipping | |
| if ( renderingShadows ) { | |
| // there's no global clipping | |
| projectPlanes( null ); | |
| } else { | |
| resetGlobalState(); | |
| } | |
| } else { | |
| var nGlobal = renderingShadows ? 0 : numGlobalPlanes, | |
| lGlobal = nGlobal * 4, | |
| dstArray = cache.clippingState || null; | |
| uniform.value = dstArray; // ensure unique state | |
| dstArray = projectPlanes( planes, camera, lGlobal, fromCache ); | |
| for ( var i = 0; i !== lGlobal; ++ i ) { | |
| dstArray[ i ] = globalState[ i ]; | |
| } | |
| cache.clippingState = dstArray; | |
| this.numIntersection = clipIntersection ? this.numPlanes : 0; | |
| this.numPlanes += nGlobal; | |
| } | |
| }; | |
| function resetGlobalState() { | |
| if ( uniform.value !== globalState ) { | |
| uniform.value = globalState; | |
| uniform.needsUpdate = numGlobalPlanes > 0; | |
| } | |
| scope.numPlanes = numGlobalPlanes; | |
| scope.numIntersection = 0; | |
| } | |
| function projectPlanes( planes, camera, dstOffset, skipTransform ) { | |
| var nPlanes = planes !== null ? planes.length : 0, | |
| dstArray = null; | |
| if ( nPlanes !== 0 ) { | |
| dstArray = uniform.value; | |
| if ( skipTransform !== true || dstArray === null ) { | |
| var flatSize = dstOffset + nPlanes * 4, | |
| viewMatrix = camera.matrixWorldInverse; | |
| viewNormalMatrix.getNormalMatrix( viewMatrix ); | |
| if ( dstArray === null || dstArray.length < flatSize ) { | |
| dstArray = new Float32Array( flatSize ); | |
| } | |
| for ( var i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) { | |
| plane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix ); | |
| plane.normal.toArray( dstArray, i4 ); | |
| dstArray[ i4 + 3 ] = plane.constant; | |
| } | |
| } | |
| uniform.value = dstArray; | |
| uniform.needsUpdate = true; | |
| } | |
| scope.numPlanes = nPlanes; | |
| return dstArray; | |
| } | |
| } | |
| export { WebGLClipping }; | |