three-stdlib 2.28.2 → 2.28.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,7 @@ var __publicField = (obj, key, value) => {
8
8
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
9
9
  const THREE = require("three");
10
10
  const _identityMatrix = new THREE.Matrix4();
11
- const _zeroMatrix = new THREE.Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
11
+ const _zeroScaleMatrix = new THREE.Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
12
12
  const batchingParsVertex = (
13
13
  /* glsl */
14
14
  `
@@ -216,7 +216,7 @@ class BatchedMesh extends THREE.Mesh {
216
216
  return this;
217
217
  }
218
218
  this._alives[geometryId] = false;
219
- _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
219
+ _zeroScaleMatrix.toArray(this._matricesArray, geometryId * 16);
220
220
  this._matricesTexture.needsUpdate = true;
221
221
  return this;
222
222
  }
@@ -250,7 +250,7 @@ class BatchedMesh extends THREE.Mesh {
250
250
  if (visible === true) {
251
251
  this._matrices[geometryId].toArray(this._matricesArray, geometryId * 16);
252
252
  } else {
253
- _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
253
+ _zeroScaleMatrix.toArray(this._matricesArray, geometryId * 16);
254
254
  }
255
255
  this._matricesTexture.needsUpdate = true;
256
256
  this._visibles[geometryId] = visible;
@@ -1 +1 @@
1
- {"version":3,"file":"BatchedMesh.cjs","sources":["../../src/objects/BatchedMesh.ts"],"sourcesContent":["import {\n Matrix4,\n Mesh,\n BufferGeometry,\n Material,\n DataTexture,\n IUniform,\n MathUtils,\n RGBAFormat,\n FloatType,\n BufferAttribute,\n} from 'three'\n\nconst _identityMatrix = new Matrix4()\nconst _zeroMatrix = new Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)\n\n// Custom shaders\nconst batchingParsVertex = /* glsl */ `\n#ifdef BATCHING\n\tattribute float id;\n\tuniform highp sampler2D batchingTexture;\n\tuniform int batchingTextureSize;\n\tmat4 getBatchingMatrix( const in float i ) {\n\t\tfloat j = i * 4.0;\n\t\tfloat x = mod( j, float( batchingTextureSize ) );\n\t\tfloat y = floor( j / float( batchingTextureSize ) );\n\t\tfloat dx = 1.0 / float( batchingTextureSize );\n\t\tfloat dy = 1.0 / float( batchingTextureSize );\n\t\ty = dy * ( y + 0.5 );\n\t\tvec4 v1 = texture2D( batchingTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\tvec4 v2 = texture2D( batchingTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\tvec4 v3 = texture2D( batchingTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\tvec4 v4 = texture2D( batchingTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif\n`\n\nconst batchingbaseVertex = /* glsl */ `\n#ifdef BATCHING\n\tmat4 batchingMatrix = getBatchingMatrix( id );\n#endif\n`\n\nconst batchingnormalVertex = /* glsl */ `\n#ifdef BATCHING\n\tobjectNormal = vec4( batchingMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( batchingMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif\n`\n\nconst batchingVertex = /* glsl */ `\n#ifdef BATCHING\n\ttransformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;\n#endif\n`\n\n// @TODO: SkinnedMesh support?\n// @TODO: Future work if needed. Move into the core. Can be optimized more with WEBGL_multi_draw.\n\nclass BatchedMesh extends Mesh<BufferGeometry, Material> {\n _vertexStarts: number[]\n _vertexCounts: number[]\n _indexStarts: number[]\n _indexCounts: number[]\n _visibles: boolean[]\n _alives: boolean[]\n _maxGeometryCount: number\n _maxVertexCount: number\n _maxIndexCount: number\n _geometryInitialized: boolean\n _geometryCount: number\n _vertexCount: number\n _indexCount: number\n _matrices: Matrix4[]\n _matricesArray: Float32Array | null\n _matricesTexture: DataTexture | null\n _matricesTextureSize: number | null\n _customUniforms: Record<string, IUniform>\n\n constructor(\n maxGeometryCount: number,\n maxVertexCount: number,\n maxIndexCount = maxVertexCount * 2,\n material?: Material,\n ) {\n super(new BufferGeometry(), material)\n\n this._vertexStarts = []\n this._vertexCounts = []\n this._indexStarts = []\n this._indexCounts = []\n\n this._visibles = []\n this._alives = []\n\n this._maxGeometryCount = maxGeometryCount\n this._maxVertexCount = maxVertexCount\n this._maxIndexCount = maxIndexCount\n\n this._geometryInitialized = false\n this._geometryCount = 0\n this._vertexCount = 0\n this._indexCount = 0\n\n // Local matrix per geometry by using data texture\n // @TODO: Support uniform parameter per geometry\n\n this._matrices = []\n this._matricesArray = null\n this._matricesTexture = null\n this._matricesTextureSize = null\n\n // @TODO: Calculate the entire binding box and make frustumCulled true\n this.frustumCulled = false\n\n this._customUniforms = {\n batchingTexture: { value: null },\n batchingTextureSize: { value: 0 },\n }\n\n this._initMatricesTexture()\n this._initShader()\n\n this.onBeforeRender = function () {\n if (this.material.defines) {\n this.material.defines.BATCHING = true\n }\n\n // @TODO: Implement frustum culling for each geometry\n }\n\n this.onAfterRender = function () {\n if (this.material.defines) {\n this.material.defines.BATCHING = false\n }\n }\n }\n\n _initMatricesTexture() {\n // layout (1 matrix = 4 pixels)\n // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n // with 8x8 pixel texture max 16 matrices * 4 pixels = (8 * 8)\n // 16x16 pixel texture max 64 matrices * 4 pixels = (16 * 16)\n // 32x32 pixel texture max 256 matrices * 4 pixels = (32 * 32)\n // 64x64 pixel texture max 1024 matrices * 4 pixels = (64 * 64)\n\n let size = Math.sqrt(this._maxGeometryCount * 4) // 4 pixels needed for 1 matrix\n size = MathUtils.ceilPowerOfTwo(size)\n size = Math.max(size, 4)\n\n const matricesArray = new Float32Array(size * size * 4) // 4 floats per RGBA pixel\n const matricesTexture = new DataTexture(matricesArray, size, size, RGBAFormat, FloatType)\n\n this._matricesArray = matricesArray\n this._matricesTexture = matricesTexture\n this._matricesTextureSize = size\n\n this._customUniforms.batchingTexture.value = this._matricesTexture\n this._customUniforms.batchingTextureSize.value = this._matricesTextureSize\n }\n\n _initShader() {\n const currentOnBeforeCompile = this.material.onBeforeCompile\n const customUniforms = this._customUniforms\n\n this.material.onBeforeCompile = function onBeforeCompile(parameters, renderer) {\n // Is this replacement stable across any materials?\n parameters.vertexShader = parameters.vertexShader\n .replace('#include <skinning_pars_vertex>', '#include <skinning_pars_vertex>\\n' + batchingParsVertex)\n .replace(\n '#include <skinnormal_vertex>',\n '#include <skinnormal_vertex>\\n' + batchingbaseVertex + batchingnormalVertex,\n )\n .replace('#include <skinning_vertex>', '#include <skinning_vertex>\\n' + batchingVertex)\n\n for (const uniformName in customUniforms) {\n parameters.uniforms[uniformName] = customUniforms[uniformName]\n }\n\n currentOnBeforeCompile.call(this, parameters, renderer)\n }\n\n this.material.defines = this.material.defines || {}\n this.material.defines.BATCHING = false\n }\n\n getGeometryCount() {\n return this._geometryCount\n }\n\n getVertexCount() {\n return this._vertexCount\n }\n\n getIndexCount() {\n return this._indexCount\n }\n\n applyGeometry(geometry: BufferGeometry) {\n // @TODO: geometry.groups support?\n // @TODO: geometry.drawRange support?\n // @TODO: geometry.mortphAttributes support?\n\n if (this._geometryCount >= this._maxGeometryCount) {\n // @TODO: Error handling\n }\n\n if (this._geometryInitialized === false) {\n for (const attributeName in geometry.attributes) {\n const srcAttribute = geometry.getAttribute(attributeName)\n const { array, itemSize, normalized } = srcAttribute\n\n const dstArray = new (array.constructor as Float32ArrayConstructor)(this._maxVertexCount * itemSize)\n const dstAttribute = new (srcAttribute.constructor as any)(dstArray, itemSize, normalized) as BufferAttribute\n\n // TODO: add usage in @types/three\n // @ts-ignore\n dstAttribute.setUsage(srcAttribute.usage)\n\n this.geometry.setAttribute(attributeName, dstAttribute)\n }\n\n if (geometry.getIndex() !== null) {\n const indexArray =\n this._maxVertexCount > 65536 ? new Uint32Array(this._maxIndexCount) : new Uint16Array(this._maxIndexCount)\n\n this.geometry.setIndex(new BufferAttribute(indexArray, 1))\n }\n\n const idArray =\n this._maxGeometryCount > 65536 ? new Uint32Array(this._maxVertexCount) : new Uint16Array(this._maxVertexCount)\n // @TODO: What if attribute name 'id' is already used?\n this.geometry.setAttribute('id', new BufferAttribute(idArray, 1))\n\n this._geometryInitialized = true\n } else {\n // @TODO: Check if geometry has the same attributes set\n }\n\n const hasIndex = this.geometry.getIndex() !== null\n const dstIndex = this.geometry.getIndex()\n const srcIndex = geometry.getIndex()\n\n // Assuming geometry has position attribute\n const srcPositionAttribute = geometry.getAttribute('position')\n\n this._vertexStarts.push(this._vertexCount)\n this._vertexCounts.push(srcPositionAttribute.count)\n\n if (hasIndex) {\n this._indexStarts.push(this._indexCount)\n this._indexCounts.push(srcIndex!.count)\n }\n\n this._visibles.push(true)\n this._alives.push(true)\n\n // @TODO: Error handling if exceeding maxVertexCount or maxIndexCount\n\n for (const attributeName in geometry.attributes) {\n const srcAttribute = geometry.getAttribute(attributeName)\n const dstAttribute = this.geometry.getAttribute(attributeName)\n ;(dstAttribute.array as Float32Array).set(srcAttribute.array, this._vertexCount * dstAttribute.itemSize)\n dstAttribute.needsUpdate = true\n }\n\n if (hasIndex) {\n for (let i = 0; i < srcIndex!.count; i++) {\n dstIndex!.setX(this._indexCount + i, this._vertexCount + srcIndex!.getX(i))\n }\n\n this._indexCount += srcIndex!.count\n dstIndex!.needsUpdate = true\n }\n\n const geometryId = this._geometryCount\n this._geometryCount++\n\n const idAttribute = this.geometry.getAttribute('id')\n\n for (let i = 0; i < srcPositionAttribute.count; i++) {\n idAttribute.setX(this._vertexCount + i, geometryId)\n }\n\n idAttribute.needsUpdate = true\n\n this._vertexCount += srcPositionAttribute.count\n\n this._matrices.push(new Matrix4())\n _identityMatrix.toArray(this._matricesArray ?? undefined, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n\n return geometryId\n }\n\n deleteGeometry(geometryId: number) {\n if (geometryId >= this._alives.length || this._alives[geometryId] === false) {\n return this\n }\n\n this._alives[geometryId] = false\n _zeroMatrix.toArray(this._matricesArray!, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n\n // User needs to call optimize() to pack the data.\n\n return this\n }\n\n optimize() {\n // @TODO: Implement\n\n return this\n }\n\n setMatrixAt(geometryId: number, matrix: Matrix4) {\n // @TODO: Map geometryId to index of the arrays because\n // optimize() can make geometryId mismatch the index\n\n if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {\n return this\n }\n\n this._matrices[geometryId].copy(matrix)\n\n if (this._visibles[geometryId] === true) {\n matrix.toArray(this._matricesArray!, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n }\n\n return this\n }\n\n getMatrixAt(geometryId: number, matrix: Matrix4) {\n if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {\n return matrix\n }\n\n return matrix.copy(this._matrices[geometryId])\n }\n\n setVisibleAt(geometryId: number, visible: boolean) {\n if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {\n return this\n }\n\n if (this._visibles[geometryId] === visible) {\n return this\n }\n\n if (visible === true) {\n this._matrices[geometryId].toArray(this._matricesArray!, geometryId * 16)\n } else {\n _zeroMatrix.toArray(this._matricesArray!, geometryId * 16)\n }\n\n this._matricesTexture!.needsUpdate = true\n this._visibles[geometryId] = visible\n return this\n }\n\n getVisibleAt(geometryId: number) {\n if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {\n return false\n }\n\n return this._visibles[geometryId]\n }\n\n copy(source: BatchedMesh) {\n // @ts-ignore\n super.copy(source)\n\n // @TODO: Implement\n\n return this\n }\n\n toJSON(meta: any) {\n // @TODO: Implement\n\n return super.toJSON(meta)\n }\n\n dispose() {\n // Assuming the geometry is not shared with other meshes\n this.geometry.dispose()\n\n this._matricesTexture?.dispose()\n this._matricesTexture = null\n\n return this\n }\n}\n\nexport { BatchedMesh }\n"],"names":["Matrix4","Mesh","BufferGeometry","MathUtils","DataTexture","RGBAFormat","FloatType","BufferAttribute"],"mappings":"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"}
1
+ {"version":3,"file":"BatchedMesh.cjs","sources":["../../src/objects/BatchedMesh.ts"],"sourcesContent":["import {\n Matrix4,\n Mesh,\n BufferGeometry,\n Material,\n DataTexture,\n IUniform,\n MathUtils,\n RGBAFormat,\n FloatType,\n BufferAttribute,\n} from 'three'\n\nconst _identityMatrix = new Matrix4()\nconst _zeroScaleMatrix = new Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)\n\n// Custom shaders\nconst batchingParsVertex = /* glsl */ `\n#ifdef BATCHING\n\tattribute float id;\n\tuniform highp sampler2D batchingTexture;\n\tuniform int batchingTextureSize;\n\tmat4 getBatchingMatrix( const in float i ) {\n\t\tfloat j = i * 4.0;\n\t\tfloat x = mod( j, float( batchingTextureSize ) );\n\t\tfloat y = floor( j / float( batchingTextureSize ) );\n\t\tfloat dx = 1.0 / float( batchingTextureSize );\n\t\tfloat dy = 1.0 / float( batchingTextureSize );\n\t\ty = dy * ( y + 0.5 );\n\t\tvec4 v1 = texture2D( batchingTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\tvec4 v2 = texture2D( batchingTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\tvec4 v3 = texture2D( batchingTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\tvec4 v4 = texture2D( batchingTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif\n`\n\nconst batchingbaseVertex = /* glsl */ `\n#ifdef BATCHING\n\tmat4 batchingMatrix = getBatchingMatrix( id );\n#endif\n`\n\nconst batchingnormalVertex = /* glsl */ `\n#ifdef BATCHING\n\tobjectNormal = vec4( batchingMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( batchingMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif\n`\n\nconst batchingVertex = /* glsl */ `\n#ifdef BATCHING\n\ttransformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;\n#endif\n`\n\n// @TODO: SkinnedMesh support?\n// @TODO: Future work if needed. Move into the core. Can be optimized more with WEBGL_multi_draw.\n\nclass BatchedMesh extends Mesh<BufferGeometry, Material> {\n _vertexStarts: number[]\n _vertexCounts: number[]\n _indexStarts: number[]\n _indexCounts: number[]\n _visibles: boolean[]\n _alives: boolean[]\n _maxGeometryCount: number\n _maxVertexCount: number\n _maxIndexCount: number\n _geometryInitialized: boolean\n _geometryCount: number\n _vertexCount: number\n _indexCount: number\n _matrices: Matrix4[]\n _matricesArray: Float32Array | null\n _matricesTexture: DataTexture | null\n _matricesTextureSize: number | null\n _customUniforms: Record<string, IUniform>\n\n constructor(\n maxGeometryCount: number,\n maxVertexCount: number,\n maxIndexCount = maxVertexCount * 2,\n material?: Material,\n ) {\n super(new BufferGeometry(), material)\n\n this._vertexStarts = []\n this._vertexCounts = []\n this._indexStarts = []\n this._indexCounts = []\n\n this._visibles = []\n this._alives = []\n\n this._maxGeometryCount = maxGeometryCount\n this._maxVertexCount = maxVertexCount\n this._maxIndexCount = maxIndexCount\n\n this._geometryInitialized = false\n this._geometryCount = 0\n this._vertexCount = 0\n this._indexCount = 0\n\n // Local matrix per geometry by using data texture\n // @TODO: Support uniform parameter per geometry\n\n this._matrices = []\n this._matricesArray = null\n this._matricesTexture = null\n this._matricesTextureSize = null\n\n // @TODO: Calculate the entire binding box and make frustumCulled true\n this.frustumCulled = false\n\n this._customUniforms = {\n batchingTexture: { value: null },\n batchingTextureSize: { value: 0 },\n }\n\n this._initMatricesTexture()\n this._initShader()\n\n this.onBeforeRender = function () {\n if (this.material.defines) {\n this.material.defines.BATCHING = true\n }\n\n // @TODO: Implement frustum culling for each geometry\n }\n\n this.onAfterRender = function () {\n if (this.material.defines) {\n this.material.defines.BATCHING = false\n }\n }\n }\n\n _initMatricesTexture() {\n // layout (1 matrix = 4 pixels)\n // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n // with 8x8 pixel texture max 16 matrices * 4 pixels = (8 * 8)\n // 16x16 pixel texture max 64 matrices * 4 pixels = (16 * 16)\n // 32x32 pixel texture max 256 matrices * 4 pixels = (32 * 32)\n // 64x64 pixel texture max 1024 matrices * 4 pixels = (64 * 64)\n\n let size = Math.sqrt(this._maxGeometryCount * 4) // 4 pixels needed for 1 matrix\n size = MathUtils.ceilPowerOfTwo(size)\n size = Math.max(size, 4)\n\n const matricesArray = new Float32Array(size * size * 4) // 4 floats per RGBA pixel\n const matricesTexture = new DataTexture(matricesArray, size, size, RGBAFormat, FloatType)\n\n this._matricesArray = matricesArray\n this._matricesTexture = matricesTexture\n this._matricesTextureSize = size\n\n this._customUniforms.batchingTexture.value = this._matricesTexture\n this._customUniforms.batchingTextureSize.value = this._matricesTextureSize\n }\n\n _initShader() {\n const currentOnBeforeCompile = this.material.onBeforeCompile\n const customUniforms = this._customUniforms\n\n this.material.onBeforeCompile = function onBeforeCompile(parameters, renderer) {\n // Is this replacement stable across any materials?\n parameters.vertexShader = parameters.vertexShader\n .replace('#include <skinning_pars_vertex>', '#include <skinning_pars_vertex>\\n' + batchingParsVertex)\n .replace(\n '#include <skinnormal_vertex>',\n '#include <skinnormal_vertex>\\n' + batchingbaseVertex + batchingnormalVertex,\n )\n .replace('#include <skinning_vertex>', '#include <skinning_vertex>\\n' + batchingVertex)\n\n for (const uniformName in customUniforms) {\n parameters.uniforms[uniformName] = customUniforms[uniformName]\n }\n\n currentOnBeforeCompile.call(this, parameters, renderer)\n }\n\n this.material.defines = this.material.defines || {}\n this.material.defines.BATCHING = false\n }\n\n getGeometryCount() {\n return this._geometryCount\n }\n\n getVertexCount() {\n return this._vertexCount\n }\n\n getIndexCount() {\n return this._indexCount\n }\n\n applyGeometry(geometry: BufferGeometry) {\n // @TODO: geometry.groups support?\n // @TODO: geometry.drawRange support?\n // @TODO: geometry.mortphAttributes support?\n\n if (this._geometryCount >= this._maxGeometryCount) {\n // @TODO: Error handling\n }\n\n if (this._geometryInitialized === false) {\n for (const attributeName in geometry.attributes) {\n const srcAttribute = geometry.getAttribute(attributeName)\n const { array, itemSize, normalized } = srcAttribute\n\n const dstArray = new (array.constructor as Float32ArrayConstructor)(this._maxVertexCount * itemSize)\n const dstAttribute = new (srcAttribute.constructor as any)(dstArray, itemSize, normalized) as BufferAttribute\n\n // TODO: add usage in @types/three\n // @ts-ignore\n dstAttribute.setUsage(srcAttribute.usage)\n\n this.geometry.setAttribute(attributeName, dstAttribute)\n }\n\n if (geometry.getIndex() !== null) {\n const indexArray =\n this._maxVertexCount > 65536 ? new Uint32Array(this._maxIndexCount) : new Uint16Array(this._maxIndexCount)\n\n this.geometry.setIndex(new BufferAttribute(indexArray, 1))\n }\n\n const idArray =\n this._maxGeometryCount > 65536 ? new Uint32Array(this._maxVertexCount) : new Uint16Array(this._maxVertexCount)\n // @TODO: What if attribute name 'id' is already used?\n this.geometry.setAttribute('id', new BufferAttribute(idArray, 1))\n\n this._geometryInitialized = true\n } else {\n // @TODO: Check if geometry has the same attributes set\n }\n\n const hasIndex = this.geometry.getIndex() !== null\n const dstIndex = this.geometry.getIndex()\n const srcIndex = geometry.getIndex()\n\n // Assuming geometry has position attribute\n const srcPositionAttribute = geometry.getAttribute('position')\n\n this._vertexStarts.push(this._vertexCount)\n this._vertexCounts.push(srcPositionAttribute.count)\n\n if (hasIndex) {\n this._indexStarts.push(this._indexCount)\n this._indexCounts.push(srcIndex!.count)\n }\n\n this._visibles.push(true)\n this._alives.push(true)\n\n // @TODO: Error handling if exceeding maxVertexCount or maxIndexCount\n\n for (const attributeName in geometry.attributes) {\n const srcAttribute = geometry.getAttribute(attributeName)\n const dstAttribute = this.geometry.getAttribute(attributeName)\n ;(dstAttribute.array as Float32Array).set(srcAttribute.array, this._vertexCount * dstAttribute.itemSize)\n dstAttribute.needsUpdate = true\n }\n\n if (hasIndex) {\n for (let i = 0; i < srcIndex!.count; i++) {\n dstIndex!.setX(this._indexCount + i, this._vertexCount + srcIndex!.getX(i))\n }\n\n this._indexCount += srcIndex!.count\n dstIndex!.needsUpdate = true\n }\n\n const geometryId = this._geometryCount\n this._geometryCount++\n\n const idAttribute = this.geometry.getAttribute('id')\n\n for (let i = 0; i < srcPositionAttribute.count; i++) {\n idAttribute.setX(this._vertexCount + i, geometryId)\n }\n\n idAttribute.needsUpdate = true\n\n this._vertexCount += srcPositionAttribute.count\n\n this._matrices.push(new Matrix4())\n _identityMatrix.toArray(this._matricesArray ?? undefined, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n\n return geometryId\n }\n\n deleteGeometry(geometryId: number) {\n if (geometryId >= this._alives.length || this._alives[geometryId] === false) {\n return this\n }\n\n this._alives[geometryId] = false\n _zeroScaleMatrix.toArray(this._matricesArray!, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n\n // User needs to call optimize() to pack the data.\n\n return this\n }\n\n optimize() {\n // @TODO: Implement\n\n return this\n }\n\n setMatrixAt(geometryId: number, matrix: Matrix4) {\n // @TODO: Map geometryId to index of the arrays because\n // optimize() can make geometryId mismatch the index\n\n if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {\n return this\n }\n\n this._matrices[geometryId].copy(matrix)\n\n if (this._visibles[geometryId] === true) {\n matrix.toArray(this._matricesArray!, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n }\n\n return this\n }\n\n getMatrixAt(geometryId: number, matrix: Matrix4) {\n if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {\n return matrix\n }\n\n return matrix.copy(this._matrices[geometryId])\n }\n\n setVisibleAt(geometryId: number, visible: boolean) {\n if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {\n return this\n }\n\n if (this._visibles[geometryId] === visible) {\n return this\n }\n\n if (visible === true) {\n this._matrices[geometryId].toArray(this._matricesArray!, geometryId * 16)\n } else {\n _zeroScaleMatrix.toArray(this._matricesArray!, geometryId * 16)\n }\n\n this._matricesTexture!.needsUpdate = true\n this._visibles[geometryId] = visible\n return this\n }\n\n getVisibleAt(geometryId: number) {\n if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {\n return false\n }\n\n return this._visibles[geometryId]\n }\n\n copy(source: BatchedMesh) {\n // @ts-ignore\n super.copy(source)\n\n // @TODO: Implement\n\n return this\n }\n\n toJSON(meta: any) {\n // @TODO: Implement\n\n return super.toJSON(meta)\n }\n\n dispose() {\n // Assuming the geometry is not shared with other meshes\n this.geometry.dispose()\n\n this._matricesTexture?.dispose()\n this._matricesTexture = null\n\n return this\n }\n}\n\nexport { BatchedMesh }\n"],"names":["Matrix4","Mesh","BufferGeometry","MathUtils","DataTexture","RGBAFormat","FloatType","BufferAttribute"],"mappings":"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"}
@@ -6,7 +6,7 @@ var __publicField = (obj, key, value) => {
6
6
  };
7
7
  import { Matrix4, Mesh, BufferGeometry, MathUtils, DataTexture, RGBAFormat, FloatType, BufferAttribute } from "three";
8
8
  const _identityMatrix = new Matrix4();
9
- const _zeroMatrix = new Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
9
+ const _zeroScaleMatrix = new Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
10
10
  const batchingParsVertex = (
11
11
  /* glsl */
12
12
  `
@@ -214,7 +214,7 @@ class BatchedMesh extends Mesh {
214
214
  return this;
215
215
  }
216
216
  this._alives[geometryId] = false;
217
- _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
217
+ _zeroScaleMatrix.toArray(this._matricesArray, geometryId * 16);
218
218
  this._matricesTexture.needsUpdate = true;
219
219
  return this;
220
220
  }
@@ -248,7 +248,7 @@ class BatchedMesh extends Mesh {
248
248
  if (visible === true) {
249
249
  this._matrices[geometryId].toArray(this._matricesArray, geometryId * 16);
250
250
  } else {
251
- _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
251
+ _zeroScaleMatrix.toArray(this._matricesArray, geometryId * 16);
252
252
  }
253
253
  this._matricesTexture.needsUpdate = true;
254
254
  this._visibles[geometryId] = visible;
@@ -1 +1 @@
1
- {"version":3,"file":"BatchedMesh.js","sources":["../../src/objects/BatchedMesh.ts"],"sourcesContent":["import {\n Matrix4,\n Mesh,\n BufferGeometry,\n Material,\n DataTexture,\n IUniform,\n MathUtils,\n RGBAFormat,\n FloatType,\n BufferAttribute,\n} from 'three'\n\nconst _identityMatrix = new Matrix4()\nconst _zeroMatrix = new Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)\n\n// Custom shaders\nconst batchingParsVertex = /* glsl */ `\n#ifdef BATCHING\n\tattribute float id;\n\tuniform highp sampler2D batchingTexture;\n\tuniform int batchingTextureSize;\n\tmat4 getBatchingMatrix( const in float i ) {\n\t\tfloat j = i * 4.0;\n\t\tfloat x = mod( j, float( batchingTextureSize ) );\n\t\tfloat y = floor( j / float( batchingTextureSize ) );\n\t\tfloat dx = 1.0 / float( batchingTextureSize );\n\t\tfloat dy = 1.0 / float( batchingTextureSize );\n\t\ty = dy * ( y + 0.5 );\n\t\tvec4 v1 = texture2D( batchingTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\tvec4 v2 = texture2D( batchingTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\tvec4 v3 = texture2D( batchingTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\tvec4 v4 = texture2D( batchingTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif\n`\n\nconst batchingbaseVertex = /* glsl */ `\n#ifdef BATCHING\n\tmat4 batchingMatrix = getBatchingMatrix( id );\n#endif\n`\n\nconst batchingnormalVertex = /* glsl */ `\n#ifdef BATCHING\n\tobjectNormal = vec4( batchingMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( batchingMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif\n`\n\nconst batchingVertex = /* glsl */ `\n#ifdef BATCHING\n\ttransformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;\n#endif\n`\n\n// @TODO: SkinnedMesh support?\n// @TODO: Future work if needed. Move into the core. Can be optimized more with WEBGL_multi_draw.\n\nclass BatchedMesh extends Mesh<BufferGeometry, Material> {\n _vertexStarts: number[]\n _vertexCounts: number[]\n _indexStarts: number[]\n _indexCounts: number[]\n _visibles: boolean[]\n _alives: boolean[]\n _maxGeometryCount: number\n _maxVertexCount: number\n _maxIndexCount: number\n _geometryInitialized: boolean\n _geometryCount: number\n _vertexCount: number\n _indexCount: number\n _matrices: Matrix4[]\n _matricesArray: Float32Array | null\n _matricesTexture: DataTexture | null\n _matricesTextureSize: number | null\n _customUniforms: Record<string, IUniform>\n\n constructor(\n maxGeometryCount: number,\n maxVertexCount: number,\n maxIndexCount = maxVertexCount * 2,\n material?: Material,\n ) {\n super(new BufferGeometry(), material)\n\n this._vertexStarts = []\n this._vertexCounts = []\n this._indexStarts = []\n this._indexCounts = []\n\n this._visibles = []\n this._alives = []\n\n this._maxGeometryCount = maxGeometryCount\n this._maxVertexCount = maxVertexCount\n this._maxIndexCount = maxIndexCount\n\n this._geometryInitialized = false\n this._geometryCount = 0\n this._vertexCount = 0\n this._indexCount = 0\n\n // Local matrix per geometry by using data texture\n // @TODO: Support uniform parameter per geometry\n\n this._matrices = []\n this._matricesArray = null\n this._matricesTexture = null\n this._matricesTextureSize = null\n\n // @TODO: Calculate the entire binding box and make frustumCulled true\n this.frustumCulled = false\n\n this._customUniforms = {\n batchingTexture: { value: null },\n batchingTextureSize: { value: 0 },\n }\n\n this._initMatricesTexture()\n this._initShader()\n\n this.onBeforeRender = function () {\n if (this.material.defines) {\n this.material.defines.BATCHING = true\n }\n\n // @TODO: Implement frustum culling for each geometry\n }\n\n this.onAfterRender = function () {\n if (this.material.defines) {\n this.material.defines.BATCHING = false\n }\n }\n }\n\n _initMatricesTexture() {\n // layout (1 matrix = 4 pixels)\n // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n // with 8x8 pixel texture max 16 matrices * 4 pixels = (8 * 8)\n // 16x16 pixel texture max 64 matrices * 4 pixels = (16 * 16)\n // 32x32 pixel texture max 256 matrices * 4 pixels = (32 * 32)\n // 64x64 pixel texture max 1024 matrices * 4 pixels = (64 * 64)\n\n let size = Math.sqrt(this._maxGeometryCount * 4) // 4 pixels needed for 1 matrix\n size = MathUtils.ceilPowerOfTwo(size)\n size = Math.max(size, 4)\n\n const matricesArray = new Float32Array(size * size * 4) // 4 floats per RGBA pixel\n const matricesTexture = new DataTexture(matricesArray, size, size, RGBAFormat, FloatType)\n\n this._matricesArray = matricesArray\n this._matricesTexture = matricesTexture\n this._matricesTextureSize = size\n\n this._customUniforms.batchingTexture.value = this._matricesTexture\n this._customUniforms.batchingTextureSize.value = this._matricesTextureSize\n }\n\n _initShader() {\n const currentOnBeforeCompile = this.material.onBeforeCompile\n const customUniforms = this._customUniforms\n\n this.material.onBeforeCompile = function onBeforeCompile(parameters, renderer) {\n // Is this replacement stable across any materials?\n parameters.vertexShader = parameters.vertexShader\n .replace('#include <skinning_pars_vertex>', '#include <skinning_pars_vertex>\\n' + batchingParsVertex)\n .replace(\n '#include <skinnormal_vertex>',\n '#include <skinnormal_vertex>\\n' + batchingbaseVertex + batchingnormalVertex,\n )\n .replace('#include <skinning_vertex>', '#include <skinning_vertex>\\n' + batchingVertex)\n\n for (const uniformName in customUniforms) {\n parameters.uniforms[uniformName] = customUniforms[uniformName]\n }\n\n currentOnBeforeCompile.call(this, parameters, renderer)\n }\n\n this.material.defines = this.material.defines || {}\n this.material.defines.BATCHING = false\n }\n\n getGeometryCount() {\n return this._geometryCount\n }\n\n getVertexCount() {\n return this._vertexCount\n }\n\n getIndexCount() {\n return this._indexCount\n }\n\n applyGeometry(geometry: BufferGeometry) {\n // @TODO: geometry.groups support?\n // @TODO: geometry.drawRange support?\n // @TODO: geometry.mortphAttributes support?\n\n if (this._geometryCount >= this._maxGeometryCount) {\n // @TODO: Error handling\n }\n\n if (this._geometryInitialized === false) {\n for (const attributeName in geometry.attributes) {\n const srcAttribute = geometry.getAttribute(attributeName)\n const { array, itemSize, normalized } = srcAttribute\n\n const dstArray = new (array.constructor as Float32ArrayConstructor)(this._maxVertexCount * itemSize)\n const dstAttribute = new (srcAttribute.constructor as any)(dstArray, itemSize, normalized) as BufferAttribute\n\n // TODO: add usage in @types/three\n // @ts-ignore\n dstAttribute.setUsage(srcAttribute.usage)\n\n this.geometry.setAttribute(attributeName, dstAttribute)\n }\n\n if (geometry.getIndex() !== null) {\n const indexArray =\n this._maxVertexCount > 65536 ? new Uint32Array(this._maxIndexCount) : new Uint16Array(this._maxIndexCount)\n\n this.geometry.setIndex(new BufferAttribute(indexArray, 1))\n }\n\n const idArray =\n this._maxGeometryCount > 65536 ? new Uint32Array(this._maxVertexCount) : new Uint16Array(this._maxVertexCount)\n // @TODO: What if attribute name 'id' is already used?\n this.geometry.setAttribute('id', new BufferAttribute(idArray, 1))\n\n this._geometryInitialized = true\n } else {\n // @TODO: Check if geometry has the same attributes set\n }\n\n const hasIndex = this.geometry.getIndex() !== null\n const dstIndex = this.geometry.getIndex()\n const srcIndex = geometry.getIndex()\n\n // Assuming geometry has position attribute\n const srcPositionAttribute = geometry.getAttribute('position')\n\n this._vertexStarts.push(this._vertexCount)\n this._vertexCounts.push(srcPositionAttribute.count)\n\n if (hasIndex) {\n this._indexStarts.push(this._indexCount)\n this._indexCounts.push(srcIndex!.count)\n }\n\n this._visibles.push(true)\n this._alives.push(true)\n\n // @TODO: Error handling if exceeding maxVertexCount or maxIndexCount\n\n for (const attributeName in geometry.attributes) {\n const srcAttribute = geometry.getAttribute(attributeName)\n const dstAttribute = this.geometry.getAttribute(attributeName)\n ;(dstAttribute.array as Float32Array).set(srcAttribute.array, this._vertexCount * dstAttribute.itemSize)\n dstAttribute.needsUpdate = true\n }\n\n if (hasIndex) {\n for (let i = 0; i < srcIndex!.count; i++) {\n dstIndex!.setX(this._indexCount + i, this._vertexCount + srcIndex!.getX(i))\n }\n\n this._indexCount += srcIndex!.count\n dstIndex!.needsUpdate = true\n }\n\n const geometryId = this._geometryCount\n this._geometryCount++\n\n const idAttribute = this.geometry.getAttribute('id')\n\n for (let i = 0; i < srcPositionAttribute.count; i++) {\n idAttribute.setX(this._vertexCount + i, geometryId)\n }\n\n idAttribute.needsUpdate = true\n\n this._vertexCount += srcPositionAttribute.count\n\n this._matrices.push(new Matrix4())\n _identityMatrix.toArray(this._matricesArray ?? undefined, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n\n return geometryId\n }\n\n deleteGeometry(geometryId: number) {\n if (geometryId >= this._alives.length || this._alives[geometryId] === false) {\n return this\n }\n\n this._alives[geometryId] = false\n _zeroMatrix.toArray(this._matricesArray!, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n\n // User needs to call optimize() to pack the data.\n\n return this\n }\n\n optimize() {\n // @TODO: Implement\n\n return this\n }\n\n setMatrixAt(geometryId: number, matrix: Matrix4) {\n // @TODO: Map geometryId to index of the arrays because\n // optimize() can make geometryId mismatch the index\n\n if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {\n return this\n }\n\n this._matrices[geometryId].copy(matrix)\n\n if (this._visibles[geometryId] === true) {\n matrix.toArray(this._matricesArray!, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n }\n\n return this\n }\n\n getMatrixAt(geometryId: number, matrix: Matrix4) {\n if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {\n return matrix\n }\n\n return matrix.copy(this._matrices[geometryId])\n }\n\n setVisibleAt(geometryId: number, visible: boolean) {\n if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {\n return this\n }\n\n if (this._visibles[geometryId] === visible) {\n return this\n }\n\n if (visible === true) {\n this._matrices[geometryId].toArray(this._matricesArray!, geometryId * 16)\n } else {\n _zeroMatrix.toArray(this._matricesArray!, geometryId * 16)\n }\n\n this._matricesTexture!.needsUpdate = true\n this._visibles[geometryId] = visible\n return this\n }\n\n getVisibleAt(geometryId: number) {\n if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {\n return false\n }\n\n return this._visibles[geometryId]\n }\n\n copy(source: BatchedMesh) {\n // @ts-ignore\n super.copy(source)\n\n // @TODO: Implement\n\n return this\n }\n\n toJSON(meta: any) {\n // @TODO: Implement\n\n return super.toJSON(meta)\n }\n\n dispose() {\n // Assuming the geometry is not shared with other meshes\n this.geometry.dispose()\n\n this._matricesTexture?.dispose()\n this._matricesTexture = null\n\n return this\n }\n}\n\nexport { BatchedMesh }\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BatchedMesh.js","sources":["../../src/objects/BatchedMesh.ts"],"sourcesContent":["import {\n Matrix4,\n Mesh,\n BufferGeometry,\n Material,\n DataTexture,\n IUniform,\n MathUtils,\n RGBAFormat,\n FloatType,\n BufferAttribute,\n} from 'three'\n\nconst _identityMatrix = new Matrix4()\nconst _zeroScaleMatrix = new Matrix4().set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)\n\n// Custom shaders\nconst batchingParsVertex = /* glsl */ `\n#ifdef BATCHING\n\tattribute float id;\n\tuniform highp sampler2D batchingTexture;\n\tuniform int batchingTextureSize;\n\tmat4 getBatchingMatrix( const in float i ) {\n\t\tfloat j = i * 4.0;\n\t\tfloat x = mod( j, float( batchingTextureSize ) );\n\t\tfloat y = floor( j / float( batchingTextureSize ) );\n\t\tfloat dx = 1.0 / float( batchingTextureSize );\n\t\tfloat dy = 1.0 / float( batchingTextureSize );\n\t\ty = dy * ( y + 0.5 );\n\t\tvec4 v1 = texture2D( batchingTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\tvec4 v2 = texture2D( batchingTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\tvec4 v3 = texture2D( batchingTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\tvec4 v4 = texture2D( batchingTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif\n`\n\nconst batchingbaseVertex = /* glsl */ `\n#ifdef BATCHING\n\tmat4 batchingMatrix = getBatchingMatrix( id );\n#endif\n`\n\nconst batchingnormalVertex = /* glsl */ `\n#ifdef BATCHING\n\tobjectNormal = vec4( batchingMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( batchingMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif\n`\n\nconst batchingVertex = /* glsl */ `\n#ifdef BATCHING\n\ttransformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;\n#endif\n`\n\n// @TODO: SkinnedMesh support?\n// @TODO: Future work if needed. Move into the core. Can be optimized more with WEBGL_multi_draw.\n\nclass BatchedMesh extends Mesh<BufferGeometry, Material> {\n _vertexStarts: number[]\n _vertexCounts: number[]\n _indexStarts: number[]\n _indexCounts: number[]\n _visibles: boolean[]\n _alives: boolean[]\n _maxGeometryCount: number\n _maxVertexCount: number\n _maxIndexCount: number\n _geometryInitialized: boolean\n _geometryCount: number\n _vertexCount: number\n _indexCount: number\n _matrices: Matrix4[]\n _matricesArray: Float32Array | null\n _matricesTexture: DataTexture | null\n _matricesTextureSize: number | null\n _customUniforms: Record<string, IUniform>\n\n constructor(\n maxGeometryCount: number,\n maxVertexCount: number,\n maxIndexCount = maxVertexCount * 2,\n material?: Material,\n ) {\n super(new BufferGeometry(), material)\n\n this._vertexStarts = []\n this._vertexCounts = []\n this._indexStarts = []\n this._indexCounts = []\n\n this._visibles = []\n this._alives = []\n\n this._maxGeometryCount = maxGeometryCount\n this._maxVertexCount = maxVertexCount\n this._maxIndexCount = maxIndexCount\n\n this._geometryInitialized = false\n this._geometryCount = 0\n this._vertexCount = 0\n this._indexCount = 0\n\n // Local matrix per geometry by using data texture\n // @TODO: Support uniform parameter per geometry\n\n this._matrices = []\n this._matricesArray = null\n this._matricesTexture = null\n this._matricesTextureSize = null\n\n // @TODO: Calculate the entire binding box and make frustumCulled true\n this.frustumCulled = false\n\n this._customUniforms = {\n batchingTexture: { value: null },\n batchingTextureSize: { value: 0 },\n }\n\n this._initMatricesTexture()\n this._initShader()\n\n this.onBeforeRender = function () {\n if (this.material.defines) {\n this.material.defines.BATCHING = true\n }\n\n // @TODO: Implement frustum culling for each geometry\n }\n\n this.onAfterRender = function () {\n if (this.material.defines) {\n this.material.defines.BATCHING = false\n }\n }\n }\n\n _initMatricesTexture() {\n // layout (1 matrix = 4 pixels)\n // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)\n // with 8x8 pixel texture max 16 matrices * 4 pixels = (8 * 8)\n // 16x16 pixel texture max 64 matrices * 4 pixels = (16 * 16)\n // 32x32 pixel texture max 256 matrices * 4 pixels = (32 * 32)\n // 64x64 pixel texture max 1024 matrices * 4 pixels = (64 * 64)\n\n let size = Math.sqrt(this._maxGeometryCount * 4) // 4 pixels needed for 1 matrix\n size = MathUtils.ceilPowerOfTwo(size)\n size = Math.max(size, 4)\n\n const matricesArray = new Float32Array(size * size * 4) // 4 floats per RGBA pixel\n const matricesTexture = new DataTexture(matricesArray, size, size, RGBAFormat, FloatType)\n\n this._matricesArray = matricesArray\n this._matricesTexture = matricesTexture\n this._matricesTextureSize = size\n\n this._customUniforms.batchingTexture.value = this._matricesTexture\n this._customUniforms.batchingTextureSize.value = this._matricesTextureSize\n }\n\n _initShader() {\n const currentOnBeforeCompile = this.material.onBeforeCompile\n const customUniforms = this._customUniforms\n\n this.material.onBeforeCompile = function onBeforeCompile(parameters, renderer) {\n // Is this replacement stable across any materials?\n parameters.vertexShader = parameters.vertexShader\n .replace('#include <skinning_pars_vertex>', '#include <skinning_pars_vertex>\\n' + batchingParsVertex)\n .replace(\n '#include <skinnormal_vertex>',\n '#include <skinnormal_vertex>\\n' + batchingbaseVertex + batchingnormalVertex,\n )\n .replace('#include <skinning_vertex>', '#include <skinning_vertex>\\n' + batchingVertex)\n\n for (const uniformName in customUniforms) {\n parameters.uniforms[uniformName] = customUniforms[uniformName]\n }\n\n currentOnBeforeCompile.call(this, parameters, renderer)\n }\n\n this.material.defines = this.material.defines || {}\n this.material.defines.BATCHING = false\n }\n\n getGeometryCount() {\n return this._geometryCount\n }\n\n getVertexCount() {\n return this._vertexCount\n }\n\n getIndexCount() {\n return this._indexCount\n }\n\n applyGeometry(geometry: BufferGeometry) {\n // @TODO: geometry.groups support?\n // @TODO: geometry.drawRange support?\n // @TODO: geometry.mortphAttributes support?\n\n if (this._geometryCount >= this._maxGeometryCount) {\n // @TODO: Error handling\n }\n\n if (this._geometryInitialized === false) {\n for (const attributeName in geometry.attributes) {\n const srcAttribute = geometry.getAttribute(attributeName)\n const { array, itemSize, normalized } = srcAttribute\n\n const dstArray = new (array.constructor as Float32ArrayConstructor)(this._maxVertexCount * itemSize)\n const dstAttribute = new (srcAttribute.constructor as any)(dstArray, itemSize, normalized) as BufferAttribute\n\n // TODO: add usage in @types/three\n // @ts-ignore\n dstAttribute.setUsage(srcAttribute.usage)\n\n this.geometry.setAttribute(attributeName, dstAttribute)\n }\n\n if (geometry.getIndex() !== null) {\n const indexArray =\n this._maxVertexCount > 65536 ? new Uint32Array(this._maxIndexCount) : new Uint16Array(this._maxIndexCount)\n\n this.geometry.setIndex(new BufferAttribute(indexArray, 1))\n }\n\n const idArray =\n this._maxGeometryCount > 65536 ? new Uint32Array(this._maxVertexCount) : new Uint16Array(this._maxVertexCount)\n // @TODO: What if attribute name 'id' is already used?\n this.geometry.setAttribute('id', new BufferAttribute(idArray, 1))\n\n this._geometryInitialized = true\n } else {\n // @TODO: Check if geometry has the same attributes set\n }\n\n const hasIndex = this.geometry.getIndex() !== null\n const dstIndex = this.geometry.getIndex()\n const srcIndex = geometry.getIndex()\n\n // Assuming geometry has position attribute\n const srcPositionAttribute = geometry.getAttribute('position')\n\n this._vertexStarts.push(this._vertexCount)\n this._vertexCounts.push(srcPositionAttribute.count)\n\n if (hasIndex) {\n this._indexStarts.push(this._indexCount)\n this._indexCounts.push(srcIndex!.count)\n }\n\n this._visibles.push(true)\n this._alives.push(true)\n\n // @TODO: Error handling if exceeding maxVertexCount or maxIndexCount\n\n for (const attributeName in geometry.attributes) {\n const srcAttribute = geometry.getAttribute(attributeName)\n const dstAttribute = this.geometry.getAttribute(attributeName)\n ;(dstAttribute.array as Float32Array).set(srcAttribute.array, this._vertexCount * dstAttribute.itemSize)\n dstAttribute.needsUpdate = true\n }\n\n if (hasIndex) {\n for (let i = 0; i < srcIndex!.count; i++) {\n dstIndex!.setX(this._indexCount + i, this._vertexCount + srcIndex!.getX(i))\n }\n\n this._indexCount += srcIndex!.count\n dstIndex!.needsUpdate = true\n }\n\n const geometryId = this._geometryCount\n this._geometryCount++\n\n const idAttribute = this.geometry.getAttribute('id')\n\n for (let i = 0; i < srcPositionAttribute.count; i++) {\n idAttribute.setX(this._vertexCount + i, geometryId)\n }\n\n idAttribute.needsUpdate = true\n\n this._vertexCount += srcPositionAttribute.count\n\n this._matrices.push(new Matrix4())\n _identityMatrix.toArray(this._matricesArray ?? undefined, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n\n return geometryId\n }\n\n deleteGeometry(geometryId: number) {\n if (geometryId >= this._alives.length || this._alives[geometryId] === false) {\n return this\n }\n\n this._alives[geometryId] = false\n _zeroScaleMatrix.toArray(this._matricesArray!, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n\n // User needs to call optimize() to pack the data.\n\n return this\n }\n\n optimize() {\n // @TODO: Implement\n\n return this\n }\n\n setMatrixAt(geometryId: number, matrix: Matrix4) {\n // @TODO: Map geometryId to index of the arrays because\n // optimize() can make geometryId mismatch the index\n\n if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {\n return this\n }\n\n this._matrices[geometryId].copy(matrix)\n\n if (this._visibles[geometryId] === true) {\n matrix.toArray(this._matricesArray!, geometryId * 16)\n this._matricesTexture!.needsUpdate = true\n }\n\n return this\n }\n\n getMatrixAt(geometryId: number, matrix: Matrix4) {\n if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {\n return matrix\n }\n\n return matrix.copy(this._matrices[geometryId])\n }\n\n setVisibleAt(geometryId: number, visible: boolean) {\n if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {\n return this\n }\n\n if (this._visibles[geometryId] === visible) {\n return this\n }\n\n if (visible === true) {\n this._matrices[geometryId].toArray(this._matricesArray!, geometryId * 16)\n } else {\n _zeroScaleMatrix.toArray(this._matricesArray!, geometryId * 16)\n }\n\n this._matricesTexture!.needsUpdate = true\n this._visibles[geometryId] = visible\n return this\n }\n\n getVisibleAt(geometryId: number) {\n if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {\n return false\n }\n\n return this._visibles[geometryId]\n }\n\n copy(source: BatchedMesh) {\n // @ts-ignore\n super.copy(source)\n\n // @TODO: Implement\n\n return this\n }\n\n toJSON(meta: any) {\n // @TODO: Implement\n\n return super.toJSON(meta)\n }\n\n dispose() {\n // Assuming the geometry is not shared with other meshes\n this.geometry.dispose()\n\n this._matricesTexture?.dispose()\n this._matricesTexture = null\n\n return this\n }\n}\n\nexport { BatchedMesh }\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "three-stdlib",
3
- "version": "2.28.2",
3
+ "version": "2.28.3",
4
4
  "description": "stand-alone library of threejs examples",
5
5
  "keywords": [
6
6
  "three",