three-stdlib 2.27.3 → 2.28.1

Sign up to get free protection for your applications and to get access to all the features.
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,281 @@
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
+ this.onBeforeRender = function() {
108
+ if (this.material.defines) {
109
+ this.material.defines.BATCHING = true;
110
+ }
111
+ };
112
+ this.onAfterRender = function() {
113
+ if (this.material.defines) {
114
+ this.material.defines.BATCHING = false;
115
+ }
116
+ };
117
+ }
118
+ _initMatricesTexture() {
119
+ let size = Math.sqrt(this._maxGeometryCount * 4);
120
+ size = THREE.MathUtils.ceilPowerOfTwo(size);
121
+ size = Math.max(size, 4);
122
+ const matricesArray = new Float32Array(size * size * 4);
123
+ const matricesTexture = new THREE.DataTexture(matricesArray, size, size, THREE.RGBAFormat, THREE.FloatType);
124
+ this._matricesArray = matricesArray;
125
+ this._matricesTexture = matricesTexture;
126
+ this._matricesTextureSize = size;
127
+ this._customUniforms.batchingTexture.value = this._matricesTexture;
128
+ this._customUniforms.batchingTextureSize.value = this._matricesTextureSize;
129
+ }
130
+ _initShader() {
131
+ const currentOnBeforeCompile = this.material.onBeforeCompile;
132
+ const customUniforms = this._customUniforms;
133
+ this.material.onBeforeCompile = function onBeforeCompile(parameters, renderer) {
134
+ parameters.vertexShader = parameters.vertexShader.replace("#include <skinning_pars_vertex>", "#include <skinning_pars_vertex>\n" + batchingParsVertex).replace(
135
+ "#include <skinnormal_vertex>",
136
+ "#include <skinnormal_vertex>\n" + batchingbaseVertex + batchingnormalVertex
137
+ ).replace("#include <skinning_vertex>", "#include <skinning_vertex>\n" + batchingVertex);
138
+ for (const uniformName in customUniforms) {
139
+ parameters.uniforms[uniformName] = customUniforms[uniformName];
140
+ }
141
+ currentOnBeforeCompile.call(this, parameters, renderer);
142
+ };
143
+ this.material.defines = this.material.defines || {};
144
+ this.material.defines.BATCHING = false;
145
+ }
146
+ getGeometryCount() {
147
+ return this._geometryCount;
148
+ }
149
+ getVertexCount() {
150
+ return this._vertexCount;
151
+ }
152
+ getIndexCount() {
153
+ return this._indexCount;
154
+ }
155
+ applyGeometry(geometry) {
156
+ var _a;
157
+ if (this._geometryCount >= this._maxGeometryCount)
158
+ ;
159
+ if (this._geometryInitialized === false) {
160
+ for (const attributeName in geometry.attributes) {
161
+ const srcAttribute = geometry.getAttribute(attributeName);
162
+ const { array, itemSize, normalized } = srcAttribute;
163
+ const dstArray = new array.constructor(this._maxVertexCount * itemSize);
164
+ const dstAttribute = new srcAttribute.constructor(dstArray, itemSize, normalized);
165
+ dstAttribute.setUsage(srcAttribute.usage);
166
+ this.geometry.setAttribute(attributeName, dstAttribute);
167
+ }
168
+ if (geometry.getIndex() !== null) {
169
+ const indexArray = this._maxVertexCount > 65536 ? new Uint32Array(this._maxIndexCount) : new Uint16Array(this._maxIndexCount);
170
+ this.geometry.setIndex(new THREE.BufferAttribute(indexArray, 1));
171
+ }
172
+ const idArray = this._maxGeometryCount > 65536 ? new Uint32Array(this._maxVertexCount) : new Uint16Array(this._maxVertexCount);
173
+ this.geometry.setAttribute("id", new THREE.BufferAttribute(idArray, 1));
174
+ this._geometryInitialized = true;
175
+ }
176
+ const hasIndex = this.geometry.getIndex() !== null;
177
+ const dstIndex = this.geometry.getIndex();
178
+ const srcIndex = geometry.getIndex();
179
+ const srcPositionAttribute = geometry.getAttribute("position");
180
+ this._vertexStarts.push(this._vertexCount);
181
+ this._vertexCounts.push(srcPositionAttribute.count);
182
+ if (hasIndex) {
183
+ this._indexStarts.push(this._indexCount);
184
+ this._indexCounts.push(srcIndex.count);
185
+ }
186
+ this._visibles.push(true);
187
+ this._alives.push(true);
188
+ for (const attributeName in geometry.attributes) {
189
+ const srcAttribute = geometry.getAttribute(attributeName);
190
+ const dstAttribute = this.geometry.getAttribute(attributeName);
191
+ dstAttribute.array.set(srcAttribute.array, this._vertexCount * dstAttribute.itemSize);
192
+ dstAttribute.needsUpdate = true;
193
+ }
194
+ if (hasIndex) {
195
+ for (let i = 0; i < srcIndex.count; i++) {
196
+ dstIndex.setX(this._indexCount + i, this._vertexCount + srcIndex.getX(i));
197
+ }
198
+ this._indexCount += srcIndex.count;
199
+ dstIndex.needsUpdate = true;
200
+ }
201
+ const geometryId = this._geometryCount;
202
+ this._geometryCount++;
203
+ const idAttribute = this.geometry.getAttribute("id");
204
+ for (let i = 0; i < srcPositionAttribute.count; i++) {
205
+ idAttribute.setX(this._vertexCount + i, geometryId);
206
+ }
207
+ idAttribute.needsUpdate = true;
208
+ this._vertexCount += srcPositionAttribute.count;
209
+ this._matrices.push(new THREE.Matrix4());
210
+ _identityMatrix.toArray((_a = this._matricesArray) != null ? _a : void 0, geometryId * 16);
211
+ this._matricesTexture.needsUpdate = true;
212
+ return geometryId;
213
+ }
214
+ deleteGeometry(geometryId) {
215
+ if (geometryId >= this._alives.length || this._alives[geometryId] === false) {
216
+ return this;
217
+ }
218
+ this._alives[geometryId] = false;
219
+ _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
220
+ this._matricesTexture.needsUpdate = true;
221
+ return this;
222
+ }
223
+ optimize() {
224
+ return this;
225
+ }
226
+ setMatrixAt(geometryId, matrix) {
227
+ if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {
228
+ return this;
229
+ }
230
+ this._matrices[geometryId].copy(matrix);
231
+ if (this._visibles[geometryId] === true) {
232
+ matrix.toArray(this._matricesArray, geometryId * 16);
233
+ this._matricesTexture.needsUpdate = true;
234
+ }
235
+ return this;
236
+ }
237
+ getMatrixAt(geometryId, matrix) {
238
+ if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {
239
+ return matrix;
240
+ }
241
+ return matrix.copy(this._matrices[geometryId]);
242
+ }
243
+ setVisibleAt(geometryId, visible) {
244
+ if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {
245
+ return this;
246
+ }
247
+ if (this._visibles[geometryId] === visible) {
248
+ return this;
249
+ }
250
+ if (visible === true) {
251
+ this._matrices[geometryId].toArray(this._matricesArray, geometryId * 16);
252
+ } else {
253
+ _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
254
+ }
255
+ this._matricesTexture.needsUpdate = true;
256
+ this._visibles[geometryId] = visible;
257
+ return this;
258
+ }
259
+ getVisibleAt(geometryId) {
260
+ if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {
261
+ return false;
262
+ }
263
+ return this._visibles[geometryId];
264
+ }
265
+ copy(source) {
266
+ super.copy(source);
267
+ return this;
268
+ }
269
+ toJSON(meta) {
270
+ return super.toJSON(meta);
271
+ }
272
+ dispose() {
273
+ var _a;
274
+ this.geometry.dispose();
275
+ (_a = this._matricesTexture) == null ? void 0 : _a.dispose();
276
+ this._matricesTexture = null;
277
+ return this;
278
+ }
279
+ }
280
+ exports.BatchedMesh = BatchedMesh;
281
+ //# 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 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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"}
@@ -0,0 +1,38 @@
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
+ }
38
+ export { BatchedMesh };
@@ -0,0 +1,281 @@
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
+ this.onBeforeRender = function() {
106
+ if (this.material.defines) {
107
+ this.material.defines.BATCHING = true;
108
+ }
109
+ };
110
+ this.onAfterRender = function() {
111
+ if (this.material.defines) {
112
+ this.material.defines.BATCHING = false;
113
+ }
114
+ };
115
+ }
116
+ _initMatricesTexture() {
117
+ let size = Math.sqrt(this._maxGeometryCount * 4);
118
+ size = MathUtils.ceilPowerOfTwo(size);
119
+ size = Math.max(size, 4);
120
+ const matricesArray = new Float32Array(size * size * 4);
121
+ const matricesTexture = new DataTexture(matricesArray, size, size, RGBAFormat, FloatType);
122
+ this._matricesArray = matricesArray;
123
+ this._matricesTexture = matricesTexture;
124
+ this._matricesTextureSize = size;
125
+ this._customUniforms.batchingTexture.value = this._matricesTexture;
126
+ this._customUniforms.batchingTextureSize.value = this._matricesTextureSize;
127
+ }
128
+ _initShader() {
129
+ const currentOnBeforeCompile = this.material.onBeforeCompile;
130
+ const customUniforms = this._customUniforms;
131
+ this.material.onBeforeCompile = function onBeforeCompile(parameters, renderer) {
132
+ parameters.vertexShader = parameters.vertexShader.replace("#include <skinning_pars_vertex>", "#include <skinning_pars_vertex>\n" + batchingParsVertex).replace(
133
+ "#include <skinnormal_vertex>",
134
+ "#include <skinnormal_vertex>\n" + batchingbaseVertex + batchingnormalVertex
135
+ ).replace("#include <skinning_vertex>", "#include <skinning_vertex>\n" + batchingVertex);
136
+ for (const uniformName in customUniforms) {
137
+ parameters.uniforms[uniformName] = customUniforms[uniformName];
138
+ }
139
+ currentOnBeforeCompile.call(this, parameters, renderer);
140
+ };
141
+ this.material.defines = this.material.defines || {};
142
+ this.material.defines.BATCHING = false;
143
+ }
144
+ getGeometryCount() {
145
+ return this._geometryCount;
146
+ }
147
+ getVertexCount() {
148
+ return this._vertexCount;
149
+ }
150
+ getIndexCount() {
151
+ return this._indexCount;
152
+ }
153
+ applyGeometry(geometry) {
154
+ var _a;
155
+ if (this._geometryCount >= this._maxGeometryCount)
156
+ ;
157
+ if (this._geometryInitialized === false) {
158
+ for (const attributeName in geometry.attributes) {
159
+ const srcAttribute = geometry.getAttribute(attributeName);
160
+ const { array, itemSize, normalized } = srcAttribute;
161
+ const dstArray = new array.constructor(this._maxVertexCount * itemSize);
162
+ const dstAttribute = new srcAttribute.constructor(dstArray, itemSize, normalized);
163
+ dstAttribute.setUsage(srcAttribute.usage);
164
+ this.geometry.setAttribute(attributeName, dstAttribute);
165
+ }
166
+ if (geometry.getIndex() !== null) {
167
+ const indexArray = this._maxVertexCount > 65536 ? new Uint32Array(this._maxIndexCount) : new Uint16Array(this._maxIndexCount);
168
+ this.geometry.setIndex(new BufferAttribute(indexArray, 1));
169
+ }
170
+ const idArray = this._maxGeometryCount > 65536 ? new Uint32Array(this._maxVertexCount) : new Uint16Array(this._maxVertexCount);
171
+ this.geometry.setAttribute("id", new BufferAttribute(idArray, 1));
172
+ this._geometryInitialized = true;
173
+ }
174
+ const hasIndex = this.geometry.getIndex() !== null;
175
+ const dstIndex = this.geometry.getIndex();
176
+ const srcIndex = geometry.getIndex();
177
+ const srcPositionAttribute = geometry.getAttribute("position");
178
+ this._vertexStarts.push(this._vertexCount);
179
+ this._vertexCounts.push(srcPositionAttribute.count);
180
+ if (hasIndex) {
181
+ this._indexStarts.push(this._indexCount);
182
+ this._indexCounts.push(srcIndex.count);
183
+ }
184
+ this._visibles.push(true);
185
+ this._alives.push(true);
186
+ for (const attributeName in geometry.attributes) {
187
+ const srcAttribute = geometry.getAttribute(attributeName);
188
+ const dstAttribute = this.geometry.getAttribute(attributeName);
189
+ dstAttribute.array.set(srcAttribute.array, this._vertexCount * dstAttribute.itemSize);
190
+ dstAttribute.needsUpdate = true;
191
+ }
192
+ if (hasIndex) {
193
+ for (let i = 0; i < srcIndex.count; i++) {
194
+ dstIndex.setX(this._indexCount + i, this._vertexCount + srcIndex.getX(i));
195
+ }
196
+ this._indexCount += srcIndex.count;
197
+ dstIndex.needsUpdate = true;
198
+ }
199
+ const geometryId = this._geometryCount;
200
+ this._geometryCount++;
201
+ const idAttribute = this.geometry.getAttribute("id");
202
+ for (let i = 0; i < srcPositionAttribute.count; i++) {
203
+ idAttribute.setX(this._vertexCount + i, geometryId);
204
+ }
205
+ idAttribute.needsUpdate = true;
206
+ this._vertexCount += srcPositionAttribute.count;
207
+ this._matrices.push(new Matrix4());
208
+ _identityMatrix.toArray((_a = this._matricesArray) != null ? _a : void 0, geometryId * 16);
209
+ this._matricesTexture.needsUpdate = true;
210
+ return geometryId;
211
+ }
212
+ deleteGeometry(geometryId) {
213
+ if (geometryId >= this._alives.length || this._alives[geometryId] === false) {
214
+ return this;
215
+ }
216
+ this._alives[geometryId] = false;
217
+ _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
218
+ this._matricesTexture.needsUpdate = true;
219
+ return this;
220
+ }
221
+ optimize() {
222
+ return this;
223
+ }
224
+ setMatrixAt(geometryId, matrix) {
225
+ if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {
226
+ return this;
227
+ }
228
+ this._matrices[geometryId].copy(matrix);
229
+ if (this._visibles[geometryId] === true) {
230
+ matrix.toArray(this._matricesArray, geometryId * 16);
231
+ this._matricesTexture.needsUpdate = true;
232
+ }
233
+ return this;
234
+ }
235
+ getMatrixAt(geometryId, matrix) {
236
+ if (geometryId >= this._matrices.length || this._alives[geometryId] === false) {
237
+ return matrix;
238
+ }
239
+ return matrix.copy(this._matrices[geometryId]);
240
+ }
241
+ setVisibleAt(geometryId, visible) {
242
+ if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {
243
+ return this;
244
+ }
245
+ if (this._visibles[geometryId] === visible) {
246
+ return this;
247
+ }
248
+ if (visible === true) {
249
+ this._matrices[geometryId].toArray(this._matricesArray, geometryId * 16);
250
+ } else {
251
+ _zeroMatrix.toArray(this._matricesArray, geometryId * 16);
252
+ }
253
+ this._matricesTexture.needsUpdate = true;
254
+ this._visibles[geometryId] = visible;
255
+ return this;
256
+ }
257
+ getVisibleAt(geometryId) {
258
+ if (geometryId >= this._visibles.length || this._alives[geometryId] === false) {
259
+ return false;
260
+ }
261
+ return this._visibles[geometryId];
262
+ }
263
+ copy(source) {
264
+ super.copy(source);
265
+ return this;
266
+ }
267
+ toJSON(meta) {
268
+ return super.toJSON(meta);
269
+ }
270
+ dispose() {
271
+ var _a;
272
+ this.geometry.dispose();
273
+ (_a = this._matricesTexture) == null ? void 0 : _a.dispose();
274
+ this._matricesTexture = null;
275
+ return this;
276
+ }
277
+ }
278
+ export {
279
+ BatchedMesh
280
+ };
281
+ //# 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 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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "three-stdlib",
3
- "version": "2.27.3",
3
+ "version": "2.28.1",
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": {