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 +2 -0
- package/index.cjs.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/objects/BatchedMesh.cjs +283 -0
- package/objects/BatchedMesh.cjs.map +1 -0
- package/objects/BatchedMesh.d.ts +40 -0
- package/objects/BatchedMesh.js +283 -0
- package/objects/BatchedMesh.js.map +1 -0
- package/package.json +4 -11
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":"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"}
|
@@ -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.
|
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
|
-
|
27
|
-
|
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": {
|