three-stdlib 2.27.3 → 2.28.0
Sign up to get free protection for your applications and to get access to all the features.
- 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": {
|