three-stdlib 2.27.3 → 2.28.0

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.
package/index.cjs CHANGED
@@ -36,6 +36,7 @@ const AnimationClipCreator = require("./animation/AnimationClipCreator.cjs");
36
36
  const CCDIKSolver = require("./animation/CCDIKSolver.cjs");
37
37
  const MMDPhysics = require("./animation/MMDPhysics.cjs");
38
38
  const MMDAnimationHelper = require("./animation/MMDAnimationHelper.cjs");
39
+ const BatchedMesh = require("./objects/BatchedMesh.cjs");
39
40
  const Reflector = require("./objects/Reflector.cjs");
40
41
  const Refractor = require("./objects/Refractor.cjs");
41
42
  const ShadowMesh = require("./objects/ShadowMesh.cjs");
@@ -318,6 +319,7 @@ exports.CCDIKHelper = CCDIKSolver.CCDIKHelper;
318
319
  exports.CCDIKSolver = CCDIKSolver.CCDIKSolver;
319
320
  exports.MMDPhysics = MMDPhysics.MMDPhysics;
320
321
  exports.MMDAnimationHelper = MMDAnimationHelper.MMDAnimationHelper;
322
+ exports.BatchedMesh = BatchedMesh.BatchedMesh;
321
323
  exports.Reflector = Reflector.Reflector;
322
324
  exports.Refractor = Refractor.Refractor;
323
325
  exports.ShadowMesh = ShadowMesh.ShadowMesh;
package/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/index.d.ts CHANGED
@@ -34,6 +34,7 @@ export * from './animation/AnimationClipCreator';
34
34
  export * from './animation/CCDIKSolver';
35
35
  export * from './animation/MMDPhysics';
36
36
  export * from './animation/MMDAnimationHelper';
37
+ export * from './objects/BatchedMesh';
37
38
  export * from './objects/Reflector';
38
39
  export * from './objects/Refractor';
39
40
  export * from './objects/ShadowMesh';
package/index.js CHANGED
@@ -34,6 +34,7 @@ import { AnimationClipCreator } from "./animation/AnimationClipCreator.js";
34
34
  import { CCDIKHelper, CCDIKSolver } from "./animation/CCDIKSolver.js";
35
35
  import { MMDPhysics } from "./animation/MMDPhysics.js";
36
36
  import { MMDAnimationHelper } from "./animation/MMDAnimationHelper.js";
37
+ import { BatchedMesh } from "./objects/BatchedMesh.js";
37
38
  import { Reflector } from "./objects/Reflector.js";
38
39
  import { Refractor } from "./objects/Refractor.js";
39
40
  import { ShadowMesh } from "./objects/ShadowMesh.js";
@@ -273,6 +274,7 @@ export {
273
274
  BVHLoader,
274
275
  BasicShader,
275
276
  BasisTextureLoader,
277
+ BatchedMesh,
276
278
  BleachBypassShader,
277
279
  BlendShader,
278
280
  BloomPass,
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,283 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => {
5
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
+ return value;
7
+ };
8
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
9
+ const THREE = require("three");
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);
12
+ const batchingParsVertex = (
13
+ /* glsl */
14
+ `
15
+ #ifdef BATCHING
16
+ attribute float id;
17
+ uniform highp sampler2D batchingTexture;
18
+ uniform int batchingTextureSize;
19
+ mat4 getBatchingMatrix( const in float i ) {
20
+ float j = i * 4.0;
21
+ float x = mod( j, float( batchingTextureSize ) );
22
+ float y = floor( j / float( batchingTextureSize ) );
23
+ float dx = 1.0 / float( batchingTextureSize );
24
+ float dy = 1.0 / float( batchingTextureSize );
25
+ y = dy * ( y + 0.5 );
26
+ vec4 v1 = texture2D( batchingTexture, vec2( dx * ( x + 0.5 ), y ) );
27
+ vec4 v2 = texture2D( batchingTexture, vec2( dx * ( x + 1.5 ), y ) );
28
+ vec4 v3 = texture2D( batchingTexture, vec2( dx * ( x + 2.5 ), y ) );
29
+ vec4 v4 = texture2D( batchingTexture, vec2( dx * ( x + 3.5 ), y ) );
30
+ return mat4( v1, v2, v3, v4 );
31
+ }
32
+ #endif
33
+ `
34
+ );
35
+ const batchingbaseVertex = (
36
+ /* glsl */
37
+ `
38
+ #ifdef BATCHING
39
+ mat4 batchingMatrix = getBatchingMatrix( id );
40
+ #endif
41
+ `
42
+ );
43
+ const batchingnormalVertex = (
44
+ /* glsl */
45
+ `
46
+ #ifdef BATCHING
47
+ objectNormal = vec4( batchingMatrix * vec4( objectNormal, 0.0 ) ).xyz;
48
+ #ifdef USE_TANGENT
49
+ objectTangent = vec4( batchingMatrix * vec4( objectTangent, 0.0 ) ).xyz;
50
+ #endif
51
+ #endif
52
+ `
53
+ );
54
+ const batchingVertex = (
55
+ /* glsl */
56
+ `
57
+ #ifdef BATCHING
58
+ transformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;
59
+ #endif
60
+ `
61
+ );
62
+ class BatchedMesh extends THREE.Mesh {
63
+ constructor(maxGeometryCount, maxVertexCount, maxIndexCount = maxVertexCount * 2, material) {
64
+ super(new THREE.BufferGeometry(), material);
65
+ __publicField(this, "_vertexStarts");
66
+ __publicField(this, "_vertexCounts");
67
+ __publicField(this, "_indexStarts");
68
+ __publicField(this, "_indexCounts");
69
+ __publicField(this, "_visibles");
70
+ __publicField(this, "_alives");
71
+ __publicField(this, "_maxGeometryCount");
72
+ __publicField(this, "_maxVertexCount");
73
+ __publicField(this, "_maxIndexCount");
74
+ __publicField(this, "_geometryInitialized");
75
+ __publicField(this, "_geometryCount");
76
+ __publicField(this, "_vertexCount");
77
+ __publicField(this, "_indexCount");
78
+ __publicField(this, "_matrices");
79
+ __publicField(this, "_matricesArray");
80
+ __publicField(this, "_matricesTexture");
81
+ __publicField(this, "_matricesTextureSize");
82
+ __publicField(this, "_customUniforms");
83
+ this._vertexStarts = [];
84
+ this._vertexCounts = [];
85
+ this._indexStarts = [];
86
+ this._indexCounts = [];
87
+ this._visibles = [];
88
+ this._alives = [];
89
+ this._maxGeometryCount = maxGeometryCount;
90
+ this._maxVertexCount = maxVertexCount;
91
+ this._maxIndexCount = maxIndexCount;
92
+ this._geometryInitialized = false;
93
+ this._geometryCount = 0;
94
+ this._vertexCount = 0;
95
+ this._indexCount = 0;
96
+ this._matrices = [];
97
+ this._matricesArray = null;
98
+ this._matricesTexture = null;
99
+ this._matricesTextureSize = null;
100
+ this.frustumCulled = false;
101
+ this._customUniforms = {
102
+ batchingTexture: { value: null },
103
+ batchingTextureSize: { value: 0 }
104
+ };
105
+ this._initMatricesTexture();
106
+ this._initShader();
107
+ }
108
+ _initMatricesTexture() {
109
+ let size = Math.sqrt(this._maxGeometryCount * 4);
110
+ size = THREE.MathUtils.ceilPowerOfTwo(size);
111
+ size = Math.max(size, 4);
112
+ const matricesArray = new Float32Array(size * size * 4);
113
+ const matricesTexture = new THREE.DataTexture(matricesArray, size, size, THREE.RGBAFormat, THREE.FloatType);
114
+ this._matricesArray = matricesArray;
115
+ this._matricesTexture = matricesTexture;
116
+ this._matricesTextureSize = size;
117
+ this._customUniforms.batchingTexture.value = this._matricesTexture;
118
+ this._customUniforms.batchingTextureSize.value = this._matricesTextureSize;
119
+ }
120
+ _initShader() {
121
+ const currentOnBeforeCompile = this.material.onBeforeCompile;
122
+ const customUniforms = this._customUniforms;
123
+ this.material.onBeforeCompile = function onBeforeCompile(parameters, renderer) {
124
+ parameters.vertexShader = parameters.vertexShader.replace("#include <skinning_pars_vertex>", "#include <skinning_pars_vertex>\n" + batchingParsVertex).replace(
125
+ "#include <skinnormal_vertex>",
126
+ "#include <skinnormal_vertex>\n" + batchingbaseVertex + batchingnormalVertex
127
+ ).replace("#include <skinning_vertex>", "#include <skinning_vertex>\n" + batchingVertex);
128
+ for (const uniformName in customUniforms) {
129
+ parameters.uniforms[uniformName] = customUniforms[uniformName];
130
+ }
131
+ currentOnBeforeCompile.call(this, parameters, renderer);
132
+ };
133
+ this.material.defines = this.material.defines || {};
134
+ this.material.defines.BATCHING = false;
135
+ }
136
+ getGeometryCount() {
137
+ return this._geometryCount;
138
+ }
139
+ getVertexCount() {
140
+ return this._vertexCount;
141
+ }
142
+ getIndexCount() {
143
+ return this._indexCount;
144
+ }
145
+ applyGeometry(geometry) {
146
+ var _a;
147
+ if (this._geometryCount >= this._maxGeometryCount)
148
+ ;
149
+ if (this._geometryInitialized === false) {
150
+ for (const attributeName in geometry.attributes) {
151
+ const srcAttribute = geometry.getAttribute(attributeName);
152
+ const { array, itemSize, normalized } = srcAttribute;
153
+ const dstArray = new array.constructor(this._maxVertexCount * itemSize);
154
+ const dstAttribute = new srcAttribute.constructor(dstArray, itemSize, normalized);
155
+ dstAttribute.setUsage(srcAttribute.usage);
156
+ this.geometry.setAttribute(attributeName, dstAttribute);
157
+ }
158
+ if (geometry.getIndex() !== null) {
159
+ const indexArray = this._maxVertexCount > 65536 ? new Uint32Array(this._maxIndexCount) : new Uint16Array(this._maxIndexCount);
160
+ this.geometry.setIndex(new THREE.BufferAttribute(indexArray, 1));
161
+ }
162
+ const idArray = this._maxGeometryCount > 65536 ? new Uint32Array(this._maxVertexCount) : new Uint16Array(this._maxVertexCount);
163
+ this.geometry.setAttribute("id", new THREE.BufferAttribute(idArray, 1));
164
+ this._geometryInitialized = true;
165
+ }
166
+ const hasIndex = this.geometry.getIndex() !== null;
167
+ const dstIndex = this.geometry.getIndex();
168
+ const srcIndex = geometry.getIndex();
169
+ const srcPositionAttribute = geometry.getAttribute("position");
170
+ this._vertexStarts.push(this._vertexCount);
171
+ this._vertexCounts.push(srcPositionAttribute.count);
172
+ if (hasIndex) {
173
+ this._indexStarts.push(this._indexCount);
174
+ this._indexCounts.push(srcIndex.count);
175
+ }
176
+ this._visibles.push(true);
177
+ this._alives.push(true);
178
+ for (const attributeName in geometry.attributes) {
179
+ const srcAttribute = geometry.getAttribute(attributeName);
180
+ const dstAttribute = this.geometry.getAttribute(attributeName);
181
+ dstAttribute.array.set(srcAttribute.array, this._vertexCount * dstAttribute.itemSize);
182
+ dstAttribute.needsUpdate = true;
183
+ }
184
+ if (hasIndex) {
185
+ for (let i = 0; i < srcIndex.count; i++) {
186
+ dstIndex.setX(this._indexCount + i, this._vertexCount + srcIndex.getX(i));
187
+ }
188
+ this._indexCount += srcIndex.count;
189
+ dstIndex.needsUpdate = true;
190
+ }
191
+ const geometryId = this._geometryCount;
192
+ this._geometryCount++;
193
+ const idAttribute = this.geometry.getAttribute("id");
194
+ for (let i = 0; i < srcPositionAttribute.count; i++) {
195
+ idAttribute.setX(this._vertexCount + i, geometryId);
196
+ }
197
+ idAttribute.needsUpdate = true;
198
+ this._vertexCount += srcPositionAttribute.count;
199
+ this._matrices.push(new THREE.Matrix4());
200
+ _identityMatrix.toArray((_a = this._matricesArray) != null ? _a : void 0, geometryId * 16);
201
+ this._matricesTexture.needsUpdate = true;
202
+ return geometryId;
203
+ }
204
+ deleteGeometry(geometryId) {
205
+ if (geometryId >= this._alives.length || this._alives[geometryId] === false) {
206
+ return this;
207
+ }
208
+ this._alives[geometryId] = false;
209
+ _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
210
+ this._matricesTexture.needsUpdate = true;
211
+ return this;
212
+ }
213
+ optimize() {
214
+ return this;
215
+ }
216
+ setMatrixAt(geometryId, matrix) {
217
+ if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {
218
+ return this;
219
+ }
220
+ this._matrices[geometryId].copy(matrix);
221
+ if (this._visibles[geometryId] === true) {
222
+ matrix.toArray(this._matricesArray, geometryId * 16);
223
+ this._matricesTexture.needsUpdate = true;
224
+ }
225
+ return this;
226
+ }
227
+ getMatrixAt(geometryId, matrix) {
228
+ if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {
229
+ return matrix;
230
+ }
231
+ return matrix.copy(this._matrices[geometryId]);
232
+ }
233
+ setVisibleAt(geometryId, visible) {
234
+ if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {
235
+ return this;
236
+ }
237
+ if (this._visibles[geometryId] === visible) {
238
+ return this;
239
+ }
240
+ if (visible === true) {
241
+ this._matrices[geometryId].toArray(this._matricesArray, geometryId * 16);
242
+ } else {
243
+ _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
244
+ }
245
+ this._matricesTexture.needsUpdate = true;
246
+ this._visibles[geometryId] = visible;
247
+ return this;
248
+ }
249
+ getVisibleAt(geometryId) {
250
+ if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {
251
+ return false;
252
+ }
253
+ return this._visibles[geometryId];
254
+ }
255
+ copy(source) {
256
+ super.copy(source);
257
+ return this;
258
+ }
259
+ toJSON(meta) {
260
+ return super.toJSON(meta);
261
+ }
262
+ dispose() {
263
+ var _a;
264
+ this.geometry.dispose();
265
+ (_a = this._matricesTexture) == null ? void 0 : _a.dispose();
266
+ this._matricesTexture = null;
267
+ return this;
268
+ }
269
+ // @ts-ignore
270
+ onBeforeRender() {
271
+ if (this.material.defines) {
272
+ this.material.defines.BATCHING = true;
273
+ }
274
+ }
275
+ // @ts-ignore
276
+ onAfterRender() {
277
+ if (this.material.defines) {
278
+ this.material.defines.BATCHING = false;
279
+ }
280
+ }
281
+ }
282
+ exports.BatchedMesh = BatchedMesh;
283
+ //# sourceMappingURL=BatchedMesh.cjs.map
@@ -0,0 +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\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 // @ts-ignore\n onBeforeRender() {\n if (this.material.defines) {\n this.material.defines.BATCHING = true\n }\n\n // @TODO: Implement frustum culling for each geometry\n }\n\n // @ts-ignore\n onAfterRender() {\n if (this.material.defines) {\n this.material.defines.BATCHING = false\n }\n }\n}\n\nexport { BatchedMesh }\n"],"names":["Matrix4","Mesh","BufferGeometry","MathUtils","DataTexture","RGBAFormat","FloatType","BufferAttribute"],"mappings":";;;;;;;;;AAaA,MAAM,kBAAkB,IAAIA,MAAAA;AAC5B,MAAM,cAAc,IAAIA,cAAQ,EAAE,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAGpF,MAAM;AAAA;AAAA,EAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBtC,MAAM;AAAA;AAAA,EAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAMtC,MAAM;AAAA;AAAA,EAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASxC,MAAM;AAAA;AAAA,EAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AASlC,MAAM,oBAAoBC,MAAAA,KAA+B;AAAA,EAoBvD,YACE,kBACA,gBACA,gBAAgB,iBAAiB,GACjC,UACA;AACM,UAAA,IAAIC,MAAAA,kBAAkB,QAAQ;AAzBtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAUE,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,eAAe;AACpB,SAAK,eAAe;AAEpB,SAAK,YAAY;AACjB,SAAK,UAAU;AAEf,SAAK,oBAAoB;AACzB,SAAK,kBAAkB;AACvB,SAAK,iBAAiB;AAEtB,SAAK,uBAAuB;AAC5B,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,cAAc;AAKnB,SAAK,YAAY;AACjB,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AACxB,SAAK,uBAAuB;AAG5B,SAAK,gBAAgB;AAErB,SAAK,kBAAkB;AAAA,MACrB,iBAAiB,EAAE,OAAO,KAAK;AAAA,MAC/B,qBAAqB,EAAE,OAAO,EAAE;AAAA,IAAA;AAGlC,SAAK,qBAAqB;AAC1B,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,uBAAuB;AAQrB,QAAI,OAAO,KAAK,KAAK,KAAK,oBAAoB,CAAC;AACxC,WAAAC,MAAA,UAAU,eAAe,IAAI;AAC7B,WAAA,KAAK,IAAI,MAAM,CAAC;AAEvB,UAAM,gBAAgB,IAAI,aAAa,OAAO,OAAO,CAAC;AACtD,UAAM,kBAAkB,IAAIC,MAAAA,YAAY,eAAe,MAAM,MAAMC,MAAAA,YAAYC,MAAAA,SAAS;AAExF,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AACxB,SAAK,uBAAuB;AAEvB,SAAA,gBAAgB,gBAAgB,QAAQ,KAAK;AAC7C,SAAA,gBAAgB,oBAAoB,QAAQ,KAAK;AAAA,EACxD;AAAA,EAEA,cAAc;AACN,UAAA,yBAAyB,KAAK,SAAS;AAC7C,UAAM,iBAAiB,KAAK;AAE5B,SAAK,SAAS,kBAAkB,SAAS,gBAAgB,YAAY,UAAU;AAE7E,iBAAW,eAAe,WAAW,aAClC,QAAQ,mCAAmC,sCAAsC,kBAAkB,EACnG;AAAA,QACC;AAAA,QACA,mCAAmC,qBAAqB;AAAA,MAEzD,EAAA,QAAQ,8BAA8B,iCAAiC,cAAc;AAExF,iBAAW,eAAe,gBAAgB;AACxC,mBAAW,SAAS,WAAW,IAAI,eAAe,WAAW;AAAA,MAC/D;AAEuB,6BAAA,KAAK,MAAM,YAAY,QAAQ;AAAA,IAAA;AAGxD,SAAK,SAAS,UAAU,KAAK,SAAS,WAAW;AAC5C,SAAA,SAAS,QAAQ,WAAW;AAAA,EACnC;AAAA,EAEA,mBAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,iBAAiB;AACf,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,gBAAgB;AACd,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,cAAc,UAA0B;;AAKlC,QAAA,KAAK,kBAAkB,KAAK;AAAmB;AAI/C,QAAA,KAAK,yBAAyB,OAAO;AAC5B,iBAAA,iBAAiB,SAAS,YAAY;AACzC,cAAA,eAAe,SAAS,aAAa,aAAa;AACxD,cAAM,EAAE,OAAO,UAAU,WAAA,IAAe;AAExC,cAAM,WAAW,IAAK,MAAM,YAAwC,KAAK,kBAAkB,QAAQ;AACnG,cAAM,eAAe,IAAK,aAAa,YAAoB,UAAU,UAAU,UAAU;AAI5E,qBAAA,SAAS,aAAa,KAAK;AAEnC,aAAA,SAAS,aAAa,eAAe,YAAY;AAAA,MACxD;AAEI,UAAA,SAAS,SAAS,MAAM,MAAM;AAChC,cAAM,aACJ,KAAK,kBAAkB,QAAQ,IAAI,YAAY,KAAK,cAAc,IAAI,IAAI,YAAY,KAAK,cAAc;AAE3G,aAAK,SAAS,SAAS,IAAIC,MAAgB,gBAAA,YAAY,CAAC,CAAC;AAAA,MAC3D;AAEA,YAAM,UACJ,KAAK,oBAAoB,QAAQ,IAAI,YAAY,KAAK,eAAe,IAAI,IAAI,YAAY,KAAK,eAAe;AAE/G,WAAK,SAAS,aAAa,MAAM,IAAIA,MAAAA,gBAAgB,SAAS,CAAC,CAAC;AAEhE,WAAK,uBAAuB;AAAA,IAG9B;AAEA,UAAM,WAAW,KAAK,SAAS,SAAA,MAAe;AACxC,UAAA,WAAW,KAAK,SAAS,SAAS;AAClC,UAAA,WAAW,SAAS;AAGpB,UAAA,uBAAuB,SAAS,aAAa,UAAU;AAExD,SAAA,cAAc,KAAK,KAAK,YAAY;AACpC,SAAA,cAAc,KAAK,qBAAqB,KAAK;AAElD,QAAI,UAAU;AACP,WAAA,aAAa,KAAK,KAAK,WAAW;AAClC,WAAA,aAAa,KAAK,SAAU,KAAK;AAAA,IACxC;AAEK,SAAA,UAAU,KAAK,IAAI;AACnB,SAAA,QAAQ,KAAK,IAAI;AAIX,eAAA,iBAAiB,SAAS,YAAY;AACzC,YAAA,eAAe,SAAS,aAAa,aAAa;AACxD,YAAM,eAAe,KAAK,SAAS,aAAa,aAAa;AAC3D,mBAAa,MAAuB,IAAI,aAAa,OAAO,KAAK,eAAe,aAAa,QAAQ;AACvG,mBAAa,cAAc;AAAA,IAC7B;AAEA,QAAI,UAAU;AACZ,eAAS,IAAI,GAAG,IAAI,SAAU,OAAO,KAAK;AAC9B,iBAAA,KAAK,KAAK,cAAc,GAAG,KAAK,eAAe,SAAU,KAAK,CAAC,CAAC;AAAA,MAC5E;AAEA,WAAK,eAAe,SAAU;AAC9B,eAAU,cAAc;AAAA,IAC1B;AAEA,UAAM,aAAa,KAAK;AACnB,SAAA;AAEL,UAAM,cAAc,KAAK,SAAS,aAAa,IAAI;AAEnD,aAAS,IAAI,GAAG,IAAI,qBAAqB,OAAO,KAAK;AACnD,kBAAY,KAAK,KAAK,eAAe,GAAG,UAAU;AAAA,IACpD;AAEA,gBAAY,cAAc;AAE1B,SAAK,gBAAgB,qBAAqB;AAE1C,SAAK,UAAU,KAAK,IAAIP,MAAAA,QAAS,CAAA;AACjC,oBAAgB,SAAQ,UAAK,mBAAL,YAAuB,QAAW,aAAa,EAAE;AACzE,SAAK,iBAAkB,cAAc;AAE9B,WAAA;AAAA,EACT;AAAA,EAEA,eAAe,YAAoB;AAC7B,QAAA,cAAc,KAAK,QAAQ,UAAU,KAAK,QAAQ,UAAU,MAAM,OAAO;AACpE,aAAA;AAAA,IACT;AAEK,SAAA,QAAQ,UAAU,IAAI;AAC3B,gBAAY,QAAQ,KAAK,gBAAiB,aAAa,EAAE;AACzD,SAAK,iBAAkB,cAAc;AAI9B,WAAA;AAAA,EACT;AAAA,EAEA,WAAW;AAGF,WAAA;AAAA,EACT;AAAA,EAEA,YAAY,YAAoB,QAAiB;AAI3C,QAAA,cAAc,KAAK,UAAU,UAAU,KAAK,QAAQ,UAAU,MAAM,OAAO;AACtE,aAAA;AAAA,IACT;AAEA,SAAK,UAAU,UAAU,EAAE,KAAK,MAAM;AAEtC,QAAI,KAAK,UAAU,UAAU,MAAM,MAAM;AACvC,aAAO,QAAQ,KAAK,gBAAiB,aAAa,EAAE;AACpD,WAAK,iBAAkB,cAAc;AAAA,IACvC;AAEO,WAAA;AAAA,EACT;AAAA,EAEA,YAAY,YAAoB,QAAiB;AAC3C,QAAA,cAAc,KAAK,UAAU,UAAU,KAAK,QAAQ,UAAU,MAAM,OAAO;AACtE,aAAA;AAAA,IACT;AAEA,WAAO,OAAO,KAAK,KAAK,UAAU,UAAU,CAAC;AAAA,EAC/C;AAAA,EAEA,aAAa,YAAoB,SAAkB;AAC7C,QAAA,cAAc,KAAK,UAAU,UAAU,KAAK,QAAQ,UAAU,MAAM,OAAO;AACtE,aAAA;AAAA,IACT;AAEA,QAAI,KAAK,UAAU,UAAU,MAAM,SAAS;AACnC,aAAA;AAAA,IACT;AAEA,QAAI,YAAY,MAAM;AACpB,WAAK,UAAU,UAAU,EAAE,QAAQ,KAAK,gBAAiB,aAAa,EAAE;AAAA,IAAA,OACnE;AACL,kBAAY,QAAQ,KAAK,gBAAiB,aAAa,EAAE;AAAA,IAC3D;AAEA,SAAK,iBAAkB,cAAc;AAChC,SAAA,UAAU,UAAU,IAAI;AACtB,WAAA;AAAA,EACT;AAAA,EAEA,aAAa,YAAoB;AAC3B,QAAA,cAAc,KAAK,UAAU,UAAU,KAAK,QAAQ,UAAU,MAAM,OAAO;AACtE,aAAA;AAAA,IACT;AAEO,WAAA,KAAK,UAAU,UAAU;AAAA,EAClC;AAAA,EAEA,KAAK,QAAqB;AAExB,UAAM,KAAK,MAAM;AAIV,WAAA;AAAA,EACT;AAAA,EAEA,OAAO,MAAW;AAGT,WAAA,MAAM,OAAO,IAAI;AAAA,EAC1B;AAAA,EAEA,UAAU;;AAER,SAAK,SAAS;AAEd,eAAK,qBAAL,mBAAuB;AACvB,SAAK,mBAAmB;AAEjB,WAAA;AAAA,EACT;AAAA;AAAA,EAGA,iBAAiB;AACX,QAAA,KAAK,SAAS,SAAS;AACpB,WAAA,SAAS,QAAQ,WAAW;AAAA,IACnC;AAAA,EAGF;AAAA;AAAA,EAGA,gBAAgB;AACV,QAAA,KAAK,SAAS,SAAS;AACpB,WAAA,SAAS,QAAQ,WAAW;AAAA,IACnC;AAAA,EACF;AACF;;"}
@@ -0,0 +1,40 @@
1
+ import { Matrix4, Mesh, BufferGeometry, Material, DataTexture, IUniform } from 'three';
2
+ declare class BatchedMesh extends Mesh<BufferGeometry, Material> {
3
+ _vertexStarts: number[];
4
+ _vertexCounts: number[];
5
+ _indexStarts: number[];
6
+ _indexCounts: number[];
7
+ _visibles: boolean[];
8
+ _alives: boolean[];
9
+ _maxGeometryCount: number;
10
+ _maxVertexCount: number;
11
+ _maxIndexCount: number;
12
+ _geometryInitialized: boolean;
13
+ _geometryCount: number;
14
+ _vertexCount: number;
15
+ _indexCount: number;
16
+ _matrices: Matrix4[];
17
+ _matricesArray: Float32Array | null;
18
+ _matricesTexture: DataTexture | null;
19
+ _matricesTextureSize: number | null;
20
+ _customUniforms: Record<string, IUniform>;
21
+ constructor(maxGeometryCount: number, maxVertexCount: number, maxIndexCount?: number, material?: Material);
22
+ _initMatricesTexture(): void;
23
+ _initShader(): void;
24
+ getGeometryCount(): number;
25
+ getVertexCount(): number;
26
+ getIndexCount(): number;
27
+ applyGeometry(geometry: BufferGeometry): number;
28
+ deleteGeometry(geometryId: number): this;
29
+ optimize(): this;
30
+ setMatrixAt(geometryId: number, matrix: Matrix4): this;
31
+ getMatrixAt(geometryId: number, matrix: Matrix4): Matrix4;
32
+ setVisibleAt(geometryId: number, visible: boolean): this;
33
+ getVisibleAt(geometryId: number): boolean;
34
+ copy(source: BatchedMesh): this;
35
+ toJSON(meta: any): any;
36
+ dispose(): this;
37
+ onBeforeRender(): void;
38
+ onAfterRender(): void;
39
+ }
40
+ export { BatchedMesh };
@@ -0,0 +1,283 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => {
4
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ return value;
6
+ };
7
+ import { Matrix4, Mesh, BufferGeometry, MathUtils, DataTexture, RGBAFormat, FloatType, BufferAttribute } from "three";
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);
10
+ const batchingParsVertex = (
11
+ /* glsl */
12
+ `
13
+ #ifdef BATCHING
14
+ attribute float id;
15
+ uniform highp sampler2D batchingTexture;
16
+ uniform int batchingTextureSize;
17
+ mat4 getBatchingMatrix( const in float i ) {
18
+ float j = i * 4.0;
19
+ float x = mod( j, float( batchingTextureSize ) );
20
+ float y = floor( j / float( batchingTextureSize ) );
21
+ float dx = 1.0 / float( batchingTextureSize );
22
+ float dy = 1.0 / float( batchingTextureSize );
23
+ y = dy * ( y + 0.5 );
24
+ vec4 v1 = texture2D( batchingTexture, vec2( dx * ( x + 0.5 ), y ) );
25
+ vec4 v2 = texture2D( batchingTexture, vec2( dx * ( x + 1.5 ), y ) );
26
+ vec4 v3 = texture2D( batchingTexture, vec2( dx * ( x + 2.5 ), y ) );
27
+ vec4 v4 = texture2D( batchingTexture, vec2( dx * ( x + 3.5 ), y ) );
28
+ return mat4( v1, v2, v3, v4 );
29
+ }
30
+ #endif
31
+ `
32
+ );
33
+ const batchingbaseVertex = (
34
+ /* glsl */
35
+ `
36
+ #ifdef BATCHING
37
+ mat4 batchingMatrix = getBatchingMatrix( id );
38
+ #endif
39
+ `
40
+ );
41
+ const batchingnormalVertex = (
42
+ /* glsl */
43
+ `
44
+ #ifdef BATCHING
45
+ objectNormal = vec4( batchingMatrix * vec4( objectNormal, 0.0 ) ).xyz;
46
+ #ifdef USE_TANGENT
47
+ objectTangent = vec4( batchingMatrix * vec4( objectTangent, 0.0 ) ).xyz;
48
+ #endif
49
+ #endif
50
+ `
51
+ );
52
+ const batchingVertex = (
53
+ /* glsl */
54
+ `
55
+ #ifdef BATCHING
56
+ transformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;
57
+ #endif
58
+ `
59
+ );
60
+ class BatchedMesh extends Mesh {
61
+ constructor(maxGeometryCount, maxVertexCount, maxIndexCount = maxVertexCount * 2, material) {
62
+ super(new BufferGeometry(), material);
63
+ __publicField(this, "_vertexStarts");
64
+ __publicField(this, "_vertexCounts");
65
+ __publicField(this, "_indexStarts");
66
+ __publicField(this, "_indexCounts");
67
+ __publicField(this, "_visibles");
68
+ __publicField(this, "_alives");
69
+ __publicField(this, "_maxGeometryCount");
70
+ __publicField(this, "_maxVertexCount");
71
+ __publicField(this, "_maxIndexCount");
72
+ __publicField(this, "_geometryInitialized");
73
+ __publicField(this, "_geometryCount");
74
+ __publicField(this, "_vertexCount");
75
+ __publicField(this, "_indexCount");
76
+ __publicField(this, "_matrices");
77
+ __publicField(this, "_matricesArray");
78
+ __publicField(this, "_matricesTexture");
79
+ __publicField(this, "_matricesTextureSize");
80
+ __publicField(this, "_customUniforms");
81
+ this._vertexStarts = [];
82
+ this._vertexCounts = [];
83
+ this._indexStarts = [];
84
+ this._indexCounts = [];
85
+ this._visibles = [];
86
+ this._alives = [];
87
+ this._maxGeometryCount = maxGeometryCount;
88
+ this._maxVertexCount = maxVertexCount;
89
+ this._maxIndexCount = maxIndexCount;
90
+ this._geometryInitialized = false;
91
+ this._geometryCount = 0;
92
+ this._vertexCount = 0;
93
+ this._indexCount = 0;
94
+ this._matrices = [];
95
+ this._matricesArray = null;
96
+ this._matricesTexture = null;
97
+ this._matricesTextureSize = null;
98
+ this.frustumCulled = false;
99
+ this._customUniforms = {
100
+ batchingTexture: { value: null },
101
+ batchingTextureSize: { value: 0 }
102
+ };
103
+ this._initMatricesTexture();
104
+ this._initShader();
105
+ }
106
+ _initMatricesTexture() {
107
+ let size = Math.sqrt(this._maxGeometryCount * 4);
108
+ size = MathUtils.ceilPowerOfTwo(size);
109
+ size = Math.max(size, 4);
110
+ const matricesArray = new Float32Array(size * size * 4);
111
+ const matricesTexture = new DataTexture(matricesArray, size, size, RGBAFormat, FloatType);
112
+ this._matricesArray = matricesArray;
113
+ this._matricesTexture = matricesTexture;
114
+ this._matricesTextureSize = size;
115
+ this._customUniforms.batchingTexture.value = this._matricesTexture;
116
+ this._customUniforms.batchingTextureSize.value = this._matricesTextureSize;
117
+ }
118
+ _initShader() {
119
+ const currentOnBeforeCompile = this.material.onBeforeCompile;
120
+ const customUniforms = this._customUniforms;
121
+ this.material.onBeforeCompile = function onBeforeCompile(parameters, renderer) {
122
+ parameters.vertexShader = parameters.vertexShader.replace("#include <skinning_pars_vertex>", "#include <skinning_pars_vertex>\n" + batchingParsVertex).replace(
123
+ "#include <skinnormal_vertex>",
124
+ "#include <skinnormal_vertex>\n" + batchingbaseVertex + batchingnormalVertex
125
+ ).replace("#include <skinning_vertex>", "#include <skinning_vertex>\n" + batchingVertex);
126
+ for (const uniformName in customUniforms) {
127
+ parameters.uniforms[uniformName] = customUniforms[uniformName];
128
+ }
129
+ currentOnBeforeCompile.call(this, parameters, renderer);
130
+ };
131
+ this.material.defines = this.material.defines || {};
132
+ this.material.defines.BATCHING = false;
133
+ }
134
+ getGeometryCount() {
135
+ return this._geometryCount;
136
+ }
137
+ getVertexCount() {
138
+ return this._vertexCount;
139
+ }
140
+ getIndexCount() {
141
+ return this._indexCount;
142
+ }
143
+ applyGeometry(geometry) {
144
+ var _a;
145
+ if (this._geometryCount >= this._maxGeometryCount)
146
+ ;
147
+ if (this._geometryInitialized === false) {
148
+ for (const attributeName in geometry.attributes) {
149
+ const srcAttribute = geometry.getAttribute(attributeName);
150
+ const { array, itemSize, normalized } = srcAttribute;
151
+ const dstArray = new array.constructor(this._maxVertexCount * itemSize);
152
+ const dstAttribute = new srcAttribute.constructor(dstArray, itemSize, normalized);
153
+ dstAttribute.setUsage(srcAttribute.usage);
154
+ this.geometry.setAttribute(attributeName, dstAttribute);
155
+ }
156
+ if (geometry.getIndex() !== null) {
157
+ const indexArray = this._maxVertexCount > 65536 ? new Uint32Array(this._maxIndexCount) : new Uint16Array(this._maxIndexCount);
158
+ this.geometry.setIndex(new BufferAttribute(indexArray, 1));
159
+ }
160
+ const idArray = this._maxGeometryCount > 65536 ? new Uint32Array(this._maxVertexCount) : new Uint16Array(this._maxVertexCount);
161
+ this.geometry.setAttribute("id", new BufferAttribute(idArray, 1));
162
+ this._geometryInitialized = true;
163
+ }
164
+ const hasIndex = this.geometry.getIndex() !== null;
165
+ const dstIndex = this.geometry.getIndex();
166
+ const srcIndex = geometry.getIndex();
167
+ const srcPositionAttribute = geometry.getAttribute("position");
168
+ this._vertexStarts.push(this._vertexCount);
169
+ this._vertexCounts.push(srcPositionAttribute.count);
170
+ if (hasIndex) {
171
+ this._indexStarts.push(this._indexCount);
172
+ this._indexCounts.push(srcIndex.count);
173
+ }
174
+ this._visibles.push(true);
175
+ this._alives.push(true);
176
+ for (const attributeName in geometry.attributes) {
177
+ const srcAttribute = geometry.getAttribute(attributeName);
178
+ const dstAttribute = this.geometry.getAttribute(attributeName);
179
+ dstAttribute.array.set(srcAttribute.array, this._vertexCount * dstAttribute.itemSize);
180
+ dstAttribute.needsUpdate = true;
181
+ }
182
+ if (hasIndex) {
183
+ for (let i = 0; i < srcIndex.count; i++) {
184
+ dstIndex.setX(this._indexCount + i, this._vertexCount + srcIndex.getX(i));
185
+ }
186
+ this._indexCount += srcIndex.count;
187
+ dstIndex.needsUpdate = true;
188
+ }
189
+ const geometryId = this._geometryCount;
190
+ this._geometryCount++;
191
+ const idAttribute = this.geometry.getAttribute("id");
192
+ for (let i = 0; i < srcPositionAttribute.count; i++) {
193
+ idAttribute.setX(this._vertexCount + i, geometryId);
194
+ }
195
+ idAttribute.needsUpdate = true;
196
+ this._vertexCount += srcPositionAttribute.count;
197
+ this._matrices.push(new Matrix4());
198
+ _identityMatrix.toArray((_a = this._matricesArray) != null ? _a : void 0, geometryId * 16);
199
+ this._matricesTexture.needsUpdate = true;
200
+ return geometryId;
201
+ }
202
+ deleteGeometry(geometryId) {
203
+ if (geometryId >= this._alives.length || this._alives[geometryId] === false) {
204
+ return this;
205
+ }
206
+ this._alives[geometryId] = false;
207
+ _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
208
+ this._matricesTexture.needsUpdate = true;
209
+ return this;
210
+ }
211
+ optimize() {
212
+ return this;
213
+ }
214
+ setMatrixAt(geometryId, matrix) {
215
+ if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {
216
+ return this;
217
+ }
218
+ this._matrices[geometryId].copy(matrix);
219
+ if (this._visibles[geometryId] === true) {
220
+ matrix.toArray(this._matricesArray, geometryId * 16);
221
+ this._matricesTexture.needsUpdate = true;
222
+ }
223
+ return this;
224
+ }
225
+ getMatrixAt(geometryId, matrix) {
226
+ if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {
227
+ return matrix;
228
+ }
229
+ return matrix.copy(this._matrices[geometryId]);
230
+ }
231
+ setVisibleAt(geometryId, visible) {
232
+ if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {
233
+ return this;
234
+ }
235
+ if (this._visibles[geometryId] === visible) {
236
+ return this;
237
+ }
238
+ if (visible === true) {
239
+ this._matrices[geometryId].toArray(this._matricesArray, geometryId * 16);
240
+ } else {
241
+ _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
242
+ }
243
+ this._matricesTexture.needsUpdate = true;
244
+ this._visibles[geometryId] = visible;
245
+ return this;
246
+ }
247
+ getVisibleAt(geometryId) {
248
+ if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {
249
+ return false;
250
+ }
251
+ return this._visibles[geometryId];
252
+ }
253
+ copy(source) {
254
+ super.copy(source);
255
+ return this;
256
+ }
257
+ toJSON(meta) {
258
+ return super.toJSON(meta);
259
+ }
260
+ dispose() {
261
+ var _a;
262
+ this.geometry.dispose();
263
+ (_a = this._matricesTexture) == null ? void 0 : _a.dispose();
264
+ this._matricesTexture = null;
265
+ return this;
266
+ }
267
+ // @ts-ignore
268
+ onBeforeRender() {
269
+ if (this.material.defines) {
270
+ this.material.defines.BATCHING = true;
271
+ }
272
+ }
273
+ // @ts-ignore
274
+ onAfterRender() {
275
+ if (this.material.defines) {
276
+ this.material.defines.BATCHING = false;
277
+ }
278
+ }
279
+ }
280
+ export {
281
+ BatchedMesh
282
+ };
283
+ //# sourceMappingURL=BatchedMesh.js.map
@@ -0,0 +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\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 // @ts-ignore\n onBeforeRender() {\n if (this.material.defines) {\n this.material.defines.BATCHING = true\n }\n\n // @TODO: Implement frustum culling for each geometry\n }\n\n // @ts-ignore\n onAfterRender() {\n if (this.material.defines) {\n this.material.defines.BATCHING = false\n }\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.27.3",
3
+ "version": "2.28.0",
4
4
  "description": "stand-alone library of threejs examples",
5
5
  "keywords": [
6
6
  "three",
@@ -22,16 +22,9 @@
22
22
  "main": "./index.cjs",
23
23
  "module": "./index.js",
24
24
  "exports": {
25
- ".": {
26
- "types": "./index.d.ts",
27
- "require": "./index.cjs",
28
- "import": "./index.js"
29
- },
30
- "./*": {
31
- "types": "./index.d.ts",
32
- "require": "./index.cjs",
33
- "import": "./index.js"
34
- }
25
+ "types": "./index.d.ts",
26
+ "require": "./index.cjs",
27
+ "import": "./index.js"
35
28
  },
36
29
  "sideEffects": false,
37
30
  "devDependencies": {