ClippingContext.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import { Matrix3 } from '../../math/Matrix3.js';
  2. import { Plane } from '../../math/Plane.js';
  3. import { Vector4 } from '../../math/Vector4.js';
  4. const _plane = /*@__PURE__*/ new Plane();
  5. class ClippingContext {
  6. constructor( parentContext = null ) {
  7. this.version = 0;
  8. this.clipIntersection = null;
  9. this.cacheKey = '';
  10. if ( parentContext === null ) {
  11. this.intersectionPlanes = [];
  12. this.unionPlanes = [];
  13. this.viewNormalMatrix = new Matrix3();
  14. this.clippingGroupContexts = new WeakMap();
  15. this.shadowPass = false;
  16. } else {
  17. this.viewNormalMatrix = parentContext.viewNormalMatrix;
  18. this.clippingGroupContexts = parentContext.clippingGroupContexts;
  19. this.shadowPass = parentContext.shadowPass;
  20. this.viewMatrix = parentContext.viewMatrix;
  21. }
  22. this.parentVersion = null;
  23. }
  24. projectPlanes( source, destination, offset ) {
  25. const l = source.length;
  26. for ( let i = 0; i < l; i ++ ) {
  27. _plane.copy( source[ i ] ).applyMatrix4( this.viewMatrix, this.viewNormalMatrix );
  28. const v = destination[ offset + i ];
  29. const normal = _plane.normal;
  30. v.x = - normal.x;
  31. v.y = - normal.y;
  32. v.z = - normal.z;
  33. v.w = _plane.constant;
  34. }
  35. }
  36. updateGlobal( scene, camera ) {
  37. this.shadowPass = ( scene.overrideMaterial !== null && scene.overrideMaterial.isShadowNodeMaterial );
  38. this.viewMatrix = camera.matrixWorldInverse;
  39. this.viewNormalMatrix.getNormalMatrix( this.viewMatrix );
  40. }
  41. update( parentContext, clippingGroup ) {
  42. let update = false;
  43. if ( parentContext.version !== this.parentVersion ) {
  44. this.intersectionPlanes = Array.from( parentContext.intersectionPlanes );
  45. this.unionPlanes = Array.from( parentContext.unionPlanes );
  46. this.parentVersion = parentContext.version;
  47. }
  48. if ( this.clipIntersection !== clippingGroup.clipIntersection ) {
  49. this.clipIntersection = clippingGroup.clipIntersection;
  50. if ( this.clipIntersection ) {
  51. this.unionPlanes.length = parentContext.unionPlanes.length;
  52. } else {
  53. this.intersectionPlanes.length = parentContext.intersectionPlanes.length;
  54. }
  55. }
  56. const srcClippingPlanes = clippingGroup.clippingPlanes;
  57. const l = srcClippingPlanes.length;
  58. let dstClippingPlanes;
  59. let offset;
  60. if ( this.clipIntersection ) {
  61. dstClippingPlanes = this.intersectionPlanes;
  62. offset = parentContext.intersectionPlanes.length;
  63. } else {
  64. dstClippingPlanes = this.unionPlanes;
  65. offset = parentContext.unionPlanes.length;
  66. }
  67. if ( dstClippingPlanes.length !== offset + l ) {
  68. dstClippingPlanes.length = offset + l;
  69. for ( let i = 0; i < l; i ++ ) {
  70. dstClippingPlanes[ offset + i ] = new Vector4();
  71. }
  72. update = true;
  73. }
  74. this.projectPlanes( srcClippingPlanes, dstClippingPlanes, offset );
  75. if ( update ) {
  76. this.version ++;
  77. this.cacheKey = `${ this.intersectionPlanes.length }:${ this.unionPlanes.length }`;
  78. }
  79. }
  80. getGroupContext( clippingGroup ) {
  81. if ( this.shadowPass && ! clippingGroup.clipShadows ) return this;
  82. let context = this.clippingGroupContexts.get( clippingGroup );
  83. if ( context === undefined ) {
  84. context = new ClippingContext( this );
  85. this.clippingGroupContexts.set( clippingGroup, context );
  86. }
  87. context.update( this, clippingGroup );
  88. return context;
  89. }
  90. get unionClippingCount() {
  91. return this.unionPlanes.length;
  92. }
  93. }
  94. export default ClippingContext;
粤ICP备19079148号