three-zoo 0.0.7 → 0.2.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/dist/GeometryComparator.d.ts +27 -0
- package/dist/InstanceAssembler.d.ts +1 -1
- package/dist/SkinnedMeshBaker.d.ts +24 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +233 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BufferGeometry } from "three";
|
|
2
|
+
/**
|
|
3
|
+
* Utility class for comparing and hashing BufferGeometry instances with tolerance support.
|
|
4
|
+
*/
|
|
5
|
+
export declare class GeometryComparator {
|
|
6
|
+
/**
|
|
7
|
+
* Generates a consistent hash for a BufferGeometry based on its contents and tolerance.
|
|
8
|
+
*
|
|
9
|
+
* @param geometry - The geometry to hash
|
|
10
|
+
* @param tolerance - Precision level for number comparison (values within tolerance are considered equal)
|
|
11
|
+
* @returns A string hash that will be identical for geometrically equivalent geometries
|
|
12
|
+
*/
|
|
13
|
+
static getGeometryHash(geometry: BufferGeometry, tolerance?: number): string;
|
|
14
|
+
/**
|
|
15
|
+
* Compares two BufferGeometry instances for approximate equality.
|
|
16
|
+
* Early exit if UUIDs match (same object or cloned geometry).
|
|
17
|
+
*/
|
|
18
|
+
static compare(firstGeometry: BufferGeometry, secondGeometry: BufferGeometry, tolerance?: number): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Generates a hash for a buffer attribute with tolerance.
|
|
21
|
+
*/
|
|
22
|
+
private static getAttributeHash;
|
|
23
|
+
/**
|
|
24
|
+
* Compares two buffer attributes with tolerance.
|
|
25
|
+
*/
|
|
26
|
+
private static compareBufferAttributes;
|
|
27
|
+
}
|
|
@@ -2,7 +2,7 @@ import { Mesh, Object3D } from "three";
|
|
|
2
2
|
interface IOptions {
|
|
3
3
|
container: Object3D;
|
|
4
4
|
filter?: (child: Mesh) => boolean;
|
|
5
|
-
|
|
5
|
+
geometryTolerance?: number;
|
|
6
6
|
}
|
|
7
7
|
export declare class InstanceAssembler {
|
|
8
8
|
static assemble(options: IOptions): void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { AnimationClip, Mesh, Object3D, SkinnedMesh } from "three";
|
|
2
|
+
/**
|
|
3
|
+
* Utilities for baking poses and animations from SkinnedMesh into a regular static Mesh.
|
|
4
|
+
*/
|
|
5
|
+
export declare class SkinnedMeshBaker {
|
|
6
|
+
/**
|
|
7
|
+
* Bakes the current pose of a SkinnedMesh into a regular geometry.
|
|
8
|
+
* Transforms all vertices according to the current skeleton state.
|
|
9
|
+
*
|
|
10
|
+
* @param skinnedMesh - SkinnedMesh from which to bake the geometry
|
|
11
|
+
* @returns A new Mesh with positions corresponding to the current bone positions
|
|
12
|
+
*/
|
|
13
|
+
static bakePose(skinnedMesh: SkinnedMesh): Mesh;
|
|
14
|
+
/**
|
|
15
|
+
* Bakes a SkinnedMesh in a specific pose derived from an AnimationClip at the given timestamp.
|
|
16
|
+
*
|
|
17
|
+
* @param armature - The parent object (typically an armature from GLTF) containing the bones
|
|
18
|
+
* @param skinnedMesh - The SkinnedMesh to be baked
|
|
19
|
+
* @param timeOffset - The animation time in seconds to set
|
|
20
|
+
* @param clip - The animation clip
|
|
21
|
+
* @returns A new Mesh with geometry matching the specified animation frame
|
|
22
|
+
*/
|
|
23
|
+
static bakeAnimationFrame(armature: Object3D, skinnedMesh: SkinnedMesh, timeOffset: number, clip: AnimationClip): Mesh;
|
|
24
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Box3, Vector3, Mesh, InstancedMesh, FrontSide, DirectionalLight, Spherical, RGBAFormat } from 'three';
|
|
1
|
+
import { Box3, Vector3, Mesh, InstancedMesh, FrontSide, BufferAttribute, AnimationMixer, DirectionalLight, Spherical, RGBAFormat } from 'three';
|
|
2
2
|
|
|
3
3
|
class Bounds extends Box3 {
|
|
4
4
|
constructor() {
|
|
@@ -84,11 +84,178 @@ class Enumerator {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Utility class for comparing and hashing BufferGeometry instances with tolerance support.
|
|
89
|
+
*/
|
|
90
|
+
class GeometryComparator {
|
|
91
|
+
/**
|
|
92
|
+
* Generates a consistent hash for a BufferGeometry based on its contents and tolerance.
|
|
93
|
+
*
|
|
94
|
+
* @param geometry - The geometry to hash
|
|
95
|
+
* @param tolerance - Precision level for number comparison (values within tolerance are considered equal)
|
|
96
|
+
* @returns A string hash that will be identical for geometrically equivalent geometries
|
|
97
|
+
*/
|
|
98
|
+
static getGeometryHash(geometry, tolerance = 1e-6) {
|
|
99
|
+
const hashParts = [];
|
|
100
|
+
// Process attributes
|
|
101
|
+
const attributes = geometry.attributes;
|
|
102
|
+
const attributeNames = Object.keys(attributes).sort(); // Sort for consistent order
|
|
103
|
+
for (const name of attributeNames) {
|
|
104
|
+
const attribute = attributes[name];
|
|
105
|
+
hashParts.push(`${name}:${attribute.itemSize}:${this.getAttributeHash(attribute, tolerance)}`);
|
|
106
|
+
}
|
|
107
|
+
// Process index if present
|
|
108
|
+
if (geometry.index) {
|
|
109
|
+
hashParts.push(`index:${this.getAttributeHash(geometry.index, tolerance)}`);
|
|
110
|
+
}
|
|
111
|
+
return hashParts.join("|");
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Compares two BufferGeometry instances for approximate equality.
|
|
115
|
+
* Early exit if UUIDs match (same object or cloned geometry).
|
|
116
|
+
*/
|
|
117
|
+
static compare(firstGeometry, secondGeometry, tolerance = 1e-6) {
|
|
118
|
+
if (firstGeometry.uuid === secondGeometry.uuid) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
// Use hash comparison for consistent results
|
|
122
|
+
return (this.getGeometryHash(firstGeometry, tolerance) ===
|
|
123
|
+
this.getGeometryHash(secondGeometry, tolerance));
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Generates a hash for a buffer attribute with tolerance.
|
|
127
|
+
*/
|
|
128
|
+
static getAttributeHash(attribute, tolerance) {
|
|
129
|
+
const array = attribute.array;
|
|
130
|
+
const itemSize = "itemSize" in attribute ? attribute.itemSize : 1;
|
|
131
|
+
const hashParts = [];
|
|
132
|
+
// Group values by their "tolerance buckets"
|
|
133
|
+
for (let i = 0; i < array.length; i += itemSize) {
|
|
134
|
+
const itemValues = [];
|
|
135
|
+
for (let j = 0; j < itemSize; j++) {
|
|
136
|
+
const val = array[i + j];
|
|
137
|
+
// Round to nearest tolerance multiple to group similar values
|
|
138
|
+
itemValues.push(Math.round(val / tolerance) * tolerance);
|
|
139
|
+
}
|
|
140
|
+
hashParts.push(itemValues.join(","));
|
|
141
|
+
}
|
|
142
|
+
return hashParts.join(";");
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Compares two buffer attributes with tolerance.
|
|
146
|
+
*/
|
|
147
|
+
static compareBufferAttributes(firstAttribute, secondAttribute, tolerance) {
|
|
148
|
+
return (this.getAttributeHash(firstAttribute, tolerance) ===
|
|
149
|
+
this.getAttributeHash(secondAttribute, tolerance));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// import {
|
|
153
|
+
// BufferAttribute,
|
|
154
|
+
// BufferGeometry,
|
|
155
|
+
// InterleavedBufferAttribute,
|
|
156
|
+
// } from "three";
|
|
157
|
+
// type AnySuitableAttribute = BufferAttribute | InterleavedBufferAttribute;
|
|
158
|
+
// /**
|
|
159
|
+
// * Utility class for comparing two BufferGeometry instances with tolerance support.
|
|
160
|
+
// * Checks geometry attributes (positions, normals, UVs, etc.) and indices (if present).
|
|
161
|
+
// */
|
|
162
|
+
// export class GeometryComparator {
|
|
163
|
+
// /**
|
|
164
|
+
// * Compares two BufferGeometry instances for approximate equality.
|
|
165
|
+
// * Early exit if UUIDs match (same object or cloned geometry).
|
|
166
|
+
// *
|
|
167
|
+
// * @param firstGeometry - The first geometry to compare.
|
|
168
|
+
// * @param secondGeometry - The second geometry to compare.
|
|
169
|
+
// * @param tolerance - Maximum allowed difference between numeric values (default: 1e-6).
|
|
170
|
+
// * @returns `true` if geometries are equivalent within tolerance, otherwise `false`.
|
|
171
|
+
// */
|
|
172
|
+
// public static compare(
|
|
173
|
+
// firstGeometry: BufferGeometry,
|
|
174
|
+
// secondGeometry: BufferGeometry,
|
|
175
|
+
// tolerance = 1e-6,
|
|
176
|
+
// ): boolean {
|
|
177
|
+
// if (firstGeometry.uuid === secondGeometry.uuid) {
|
|
178
|
+
// return true;
|
|
179
|
+
// }
|
|
180
|
+
// const firstAttributes = firstGeometry.attributes;
|
|
181
|
+
// const secondAttributes = secondGeometry.attributes;
|
|
182
|
+
// const firstAttributeNames = Object.keys(firstAttributes);
|
|
183
|
+
// const secondAttributeNames = Object.keys(secondAttributes);
|
|
184
|
+
// if (firstAttributeNames.length !== secondAttributeNames.length) {
|
|
185
|
+
// return false;
|
|
186
|
+
// }
|
|
187
|
+
// for (const attributeName of firstAttributeNames) {
|
|
188
|
+
// if (!secondAttributes[attributeName]) {
|
|
189
|
+
// return false;
|
|
190
|
+
// }
|
|
191
|
+
// const firstAttribute = firstAttributes[
|
|
192
|
+
// attributeName
|
|
193
|
+
// ] as AnySuitableAttribute;
|
|
194
|
+
// const secondAttribute = secondAttributes[
|
|
195
|
+
// attributeName
|
|
196
|
+
// ] as AnySuitableAttribute;
|
|
197
|
+
// if (
|
|
198
|
+
// firstAttribute.count !== secondAttribute.count ||
|
|
199
|
+
// firstAttribute.itemSize !== secondAttribute.itemSize ||
|
|
200
|
+
// !this.compareBufferAttributes(
|
|
201
|
+
// firstAttribute,
|
|
202
|
+
// secondAttribute,
|
|
203
|
+
// tolerance,
|
|
204
|
+
// )
|
|
205
|
+
// ) {
|
|
206
|
+
// return false;
|
|
207
|
+
// }
|
|
208
|
+
// }
|
|
209
|
+
// if (firstGeometry.index || secondGeometry.index) {
|
|
210
|
+
// if (!firstGeometry.index || !secondGeometry.index) {
|
|
211
|
+
// return false;
|
|
212
|
+
// }
|
|
213
|
+
// if (
|
|
214
|
+
// !this.compareBufferAttributes(
|
|
215
|
+
// firstGeometry.index,
|
|
216
|
+
// secondGeometry.index,
|
|
217
|
+
// tolerance,
|
|
218
|
+
// )
|
|
219
|
+
// ) {
|
|
220
|
+
// return false;
|
|
221
|
+
// }
|
|
222
|
+
// }
|
|
223
|
+
// return true;
|
|
224
|
+
// }
|
|
225
|
+
// /**
|
|
226
|
+
// * Compares two buffer attributes (or index buffers) with tolerance.
|
|
227
|
+
// *
|
|
228
|
+
// * @param firstAttribute - First attribute/indices to compare.
|
|
229
|
+
// * @param secondAttribute - Second attribute/indices to compare.
|
|
230
|
+
// * @param tolerance - Maximum allowed difference between array elements.
|
|
231
|
+
// * @returns `true` if arrays are equal within tolerance, otherwise `false`.
|
|
232
|
+
// */
|
|
233
|
+
// private static compareBufferAttributes(
|
|
234
|
+
// firstAttribute: AnySuitableAttribute,
|
|
235
|
+
// secondAttribute: AnySuitableAttribute,
|
|
236
|
+
// tolerance: number,
|
|
237
|
+
// ): boolean {
|
|
238
|
+
// const firstArray = firstAttribute.array;
|
|
239
|
+
// const secondArray = secondAttribute.array;
|
|
240
|
+
// if (firstArray.length !== secondArray.length) {
|
|
241
|
+
// return false;
|
|
242
|
+
// }
|
|
243
|
+
// for (let index = 0; index < firstArray.length; index++) {
|
|
244
|
+
// if (Math.abs(firstArray[index] - secondArray[index]) > tolerance) {
|
|
245
|
+
// return false;
|
|
246
|
+
// }
|
|
247
|
+
// }
|
|
248
|
+
// return true;
|
|
249
|
+
// }
|
|
250
|
+
// }
|
|
251
|
+
|
|
87
252
|
class InstanceAssembler {
|
|
88
253
|
static assemble(options) {
|
|
89
|
-
var _a;
|
|
254
|
+
var _a, _b;
|
|
90
255
|
const dictionary = new Map();
|
|
91
256
|
const instancedMeshes = [];
|
|
257
|
+
const tolerance = (_a = options.geometryTolerance) !== null && _a !== void 0 ? _a : 1e-6;
|
|
258
|
+
const geometryHashCache = new Map();
|
|
92
259
|
Enumerator.enumerateObjectsByType(options.container, Mesh, (child) => {
|
|
93
260
|
var _a;
|
|
94
261
|
if (child.children.length === 0 &&
|
|
@@ -96,8 +263,14 @@ class InstanceAssembler {
|
|
|
96
263
|
const materials = Array.isArray(child.material)
|
|
97
264
|
? child.material
|
|
98
265
|
: [child.material];
|
|
99
|
-
|
|
100
|
-
|
|
266
|
+
let geometryHash = geometryHashCache.get(child.geometry.uuid);
|
|
267
|
+
if (!geometryHash) {
|
|
268
|
+
geometryHash = GeometryComparator.getGeometryHash(child.geometry, tolerance);
|
|
269
|
+
geometryHashCache.set(child.geometry.uuid, geometryHash);
|
|
270
|
+
}
|
|
271
|
+
const materialKey = materials.map((m) => m.uuid).join(",");
|
|
272
|
+
const compositeKey = `${geometryHash}|${materialKey}`;
|
|
273
|
+
const entry = (_a = dictionary.get(compositeKey)) !== null && _a !== void 0 ? _a : {
|
|
101
274
|
meshes: [],
|
|
102
275
|
materials: materials,
|
|
103
276
|
castShadow: false,
|
|
@@ -108,7 +281,7 @@ class InstanceAssembler {
|
|
|
108
281
|
if (child.receiveShadow)
|
|
109
282
|
entry.receiveShadow = true;
|
|
110
283
|
entry.meshes.push(child);
|
|
111
|
-
dictionary.set(
|
|
284
|
+
dictionary.set(compositeKey, entry);
|
|
112
285
|
}
|
|
113
286
|
});
|
|
114
287
|
for (const descriptor of dictionary.values()) {
|
|
@@ -130,16 +303,12 @@ class InstanceAssembler {
|
|
|
130
303
|
instancedMesh.instanceMatrix.needsUpdate = true;
|
|
131
304
|
instancedMeshes.push(instancedMesh);
|
|
132
305
|
for (const mesh of sortedMeshes) {
|
|
133
|
-
(
|
|
134
|
-
}
|
|
135
|
-
if (options.disposeOriginal === true) {
|
|
136
|
-
for (const material of materials) {
|
|
137
|
-
material.dispose();
|
|
138
|
-
}
|
|
306
|
+
(_b = mesh.parent) === null || _b === void 0 ? void 0 : _b.remove(mesh);
|
|
139
307
|
}
|
|
140
308
|
}
|
|
141
|
-
if (instancedMeshes.length > 0)
|
|
309
|
+
if (instancedMeshes.length > 0) {
|
|
142
310
|
options.container.add(...instancedMeshes);
|
|
311
|
+
}
|
|
143
312
|
}
|
|
144
313
|
}
|
|
145
314
|
|
|
@@ -165,6 +334,57 @@ class SceneProcessor {
|
|
|
165
334
|
}
|
|
166
335
|
}
|
|
167
336
|
|
|
337
|
+
/**
|
|
338
|
+
* Utilities for baking poses and animations from SkinnedMesh into a regular static Mesh.
|
|
339
|
+
*/
|
|
340
|
+
class SkinnedMeshBaker {
|
|
341
|
+
/**
|
|
342
|
+
* Bakes the current pose of a SkinnedMesh into a regular geometry.
|
|
343
|
+
* Transforms all vertices according to the current skeleton state.
|
|
344
|
+
*
|
|
345
|
+
* @param skinnedMesh - SkinnedMesh from which to bake the geometry
|
|
346
|
+
* @returns A new Mesh with positions corresponding to the current bone positions
|
|
347
|
+
*/
|
|
348
|
+
static bakePose(skinnedMesh) {
|
|
349
|
+
const bakedGeometry = skinnedMesh.geometry.clone();
|
|
350
|
+
const position = bakedGeometry.attributes["position"];
|
|
351
|
+
const newPositions = new Float32Array(position.count * 3);
|
|
352
|
+
const target = new Vector3();
|
|
353
|
+
for (let i = 0; i < position.count; i++) {
|
|
354
|
+
target.fromBufferAttribute(position, i);
|
|
355
|
+
skinnedMesh.applyBoneTransform(i, target);
|
|
356
|
+
newPositions[i * 3 + 0] = target.x;
|
|
357
|
+
newPositions[i * 3 + 1] = target.y;
|
|
358
|
+
newPositions[i * 3 + 2] = target.z;
|
|
359
|
+
}
|
|
360
|
+
bakedGeometry.setAttribute("position", new BufferAttribute(newPositions, 3));
|
|
361
|
+
bakedGeometry.computeVertexNormals();
|
|
362
|
+
bakedGeometry.deleteAttribute("skinIndex");
|
|
363
|
+
bakedGeometry.deleteAttribute("skinWeight");
|
|
364
|
+
const mesh = new Mesh(bakedGeometry, skinnedMesh.material);
|
|
365
|
+
mesh.name = skinnedMesh.name;
|
|
366
|
+
return mesh;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Bakes a SkinnedMesh in a specific pose derived from an AnimationClip at the given timestamp.
|
|
370
|
+
*
|
|
371
|
+
* @param armature - The parent object (typically an armature from GLTF) containing the bones
|
|
372
|
+
* @param skinnedMesh - The SkinnedMesh to be baked
|
|
373
|
+
* @param timeOffset - The animation time in seconds to set
|
|
374
|
+
* @param clip - The animation clip
|
|
375
|
+
* @returns A new Mesh with geometry matching the specified animation frame
|
|
376
|
+
*/
|
|
377
|
+
static bakeAnimationFrame(armature, skinnedMesh, timeOffset, clip) {
|
|
378
|
+
const mixer = new AnimationMixer(armature);
|
|
379
|
+
const action = mixer.clipAction(clip);
|
|
380
|
+
action.play();
|
|
381
|
+
mixer.setTime(timeOffset);
|
|
382
|
+
armature.updateWorldMatrix(true, true);
|
|
383
|
+
skinnedMesh.skeleton.update();
|
|
384
|
+
return this.bakePose(skinnedMesh);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
168
388
|
class Sun extends DirectionalLight {
|
|
169
389
|
constructor() {
|
|
170
390
|
super(...arguments);
|
|
@@ -257,5 +477,5 @@ class Sun extends DirectionalLight {
|
|
|
257
477
|
}
|
|
258
478
|
}
|
|
259
479
|
|
|
260
|
-
export { Bounds, Enumerator, InstanceAssembler, SceneProcessor, Sun };
|
|
480
|
+
export { Bounds, Enumerator, InstanceAssembler, SceneProcessor, SkinnedMeshBaker, Sun };
|
|
261
481
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/Bounds.ts","../src/Enumerator.ts","../src/InstanceAssembler.ts","../src/SceneProcessor.ts","../src/Sun.ts"],"sourcesContent":["import { Box3, Vector3 } from \"three\";\n\nexport class Bounds extends Box3 {\n private readonly tempVector3: Vector3 = new Vector3();\n\n public get width(): number {\n return this.max.x - this.min.x;\n }\n\n public get height(): number {\n return this.max.y - this.min.y;\n }\n\n public get depth(): number {\n return this.max.z - this.min.z;\n }\n\n public get diagonal(): number {\n this.tempVector3.subVectors(this.max, this.min);\n return this.tempVector3.length();\n }\n}\n","import { Material, Mesh, Object3D } from \"three\";\n\ntype Constructor<T> = abstract new (...args: never[]) => T;\n\nexport class Enumerator {\n public static getObjectByName(\n object: Object3D,\n name: string,\n ): Object3D | null {\n if (object.name === name) return object;\n\n for (const child of object.children) {\n const result = Enumerator.getObjectByName(child, name);\n if (result) return result;\n }\n\n return null;\n }\n\n public static getMaterialByName(\n object: Object3D,\n name: string,\n ): Material | null {\n if (object instanceof Mesh) {\n if (Array.isArray(object.material)) {\n for (const material of object.material) {\n if (material.name === name) return material;\n }\n } else if (object.material.name === name) {\n return object.material;\n }\n }\n\n for (const child of object.children) {\n const material = Enumerator.getMaterialByName(child, name);\n if (material) return material;\n }\n\n return null;\n }\n\n public static enumerateObjectsByType<T>(\n object: Object3D,\n type: Constructor<T>,\n callback: (instance: T) => void,\n ): void {\n if (object instanceof type) {\n callback(object);\n }\n\n for (const child of object.children) {\n Enumerator.enumerateObjectsByType(child, type, callback);\n }\n }\n\n public static enumerateMaterials(\n object: Object3D,\n callback: (material: Material) => void,\n ): void {\n if (object instanceof Mesh) {\n if (Array.isArray(object.material)) {\n for (const material of object.material) {\n callback(material);\n }\n } else {\n callback(object.material);\n }\n }\n\n for (const child of object.children) {\n Enumerator.enumerateMaterials(child, callback);\n }\n }\n\n public static setShadowRecursive(\n object: Object3D,\n castShadow = true,\n receiveShadow = true,\n ): void {\n if (object instanceof Mesh || \"isMesh\" in object) {\n (object as Mesh).castShadow = castShadow;\n (object as Mesh).receiveShadow = receiveShadow;\n }\n\n for (const child of object.children) {\n Enumerator.setShadowRecursive(child, castShadow, receiveShadow);\n }\n }\n}\n","import { InstancedMesh, Material, Mesh, Object3D } from \"three\";\nimport { Enumerator } from \"./Enumerator\";\n\ninterface IMeshDescriptor {\n meshes: Mesh[];\n materials: Material[];\n castShadow: boolean;\n receiveShadow: boolean;\n}\n\ninterface IOptions {\n container: Object3D;\n filter?: (child: Mesh) => boolean;\n disposeOriginal?: boolean;\n}\n\nexport class InstanceAssembler {\n public static assemble(options: IOptions): void {\n const dictionary = new Map<string, IMeshDescriptor>();\n const instancedMeshes: InstancedMesh[] = [];\n\n Enumerator.enumerateObjectsByType(\n options.container,\n Mesh,\n (child: Mesh) => {\n if (\n child.children.length === 0 &&\n (!options.filter || options.filter(child))\n ) {\n const materials = Array.isArray(child.material)\n ? child.material\n : [child.material];\n\n const key = `${child.geometry.uuid}|${materials.map((m) => m.uuid).join(\",\")}`;\n const entry = dictionary.get(key) ?? {\n meshes: [],\n materials: materials,\n castShadow: false,\n receiveShadow: false,\n };\n\n if (child.castShadow) entry.castShadow = true;\n if (child.receiveShadow) entry.receiveShadow = true;\n\n entry.meshes.push(child);\n dictionary.set(key, entry);\n }\n },\n );\n\n for (const descriptor of dictionary.values()) {\n if (descriptor.meshes.length < 2) continue;\n const { meshes, materials, castShadow, receiveShadow } = descriptor;\n\n const sortedMeshes = meshes.sort((a, b) => a.name.localeCompare(b.name));\n const defaultMesh = sortedMeshes[0];\n\n const instancedMesh = new InstancedMesh(\n defaultMesh.geometry,\n materials.length === 1 ? materials[0] : materials,\n sortedMeshes.length,\n );\n\n instancedMesh.name = defaultMesh.name;\n instancedMesh.castShadow = castShadow;\n instancedMesh.receiveShadow = receiveShadow;\n\n for (let i = 0; i < sortedMeshes.length; i++) {\n const mesh = sortedMeshes[i];\n mesh.updateWorldMatrix(true, false);\n instancedMesh.setMatrixAt(i, mesh.matrixWorld);\n instancedMesh.userData[mesh.uuid] = mesh.userData;\n }\n\n instancedMesh.instanceMatrix.needsUpdate = true;\n instancedMeshes.push(instancedMesh);\n\n for (const mesh of sortedMeshes) {\n mesh.parent?.remove(mesh);\n }\n\n if (options.disposeOriginal === true) {\n for (const material of materials) {\n material.dispose();\n }\n }\n }\n\n if (instancedMeshes.length > 0) options.container.add(...instancedMeshes);\n }\n}\n","import { FrontSide, Material, Mesh, Object3D } from \"three\";\nimport { Enumerator } from \"./Enumerator\";\nimport { InstanceAssembler } from \"./InstanceAssembler\";\n\ntype IPattern = string | RegExp;\n\ninterface IOptions {\n asset: Object3D;\n castShadowMeshNames?: IPattern[];\n receiveShadowMeshNames?: IPattern[];\n transparentMaterialNames?: IPattern[];\n noDepthWriteMaterialNames?: IPattern[];\n}\n\nexport class SceneProcessor {\n public static process(options: IOptions): Object3D[] {\n const container = options.asset.clone();\n InstanceAssembler.assemble({ container: container });\n\n Enumerator.enumerateMaterials(container, (material: Material) => {\n material.transparent = SceneProcessor.matchesAny(\n material.name,\n options.transparentMaterialNames,\n );\n material.depthWrite = !SceneProcessor.matchesAny(\n material.name,\n options.noDepthWriteMaterialNames,\n );\n material.side = FrontSide;\n material.forceSinglePass = true;\n material.depthTest = true;\n });\n\n Enumerator.enumerateObjectsByType(container, Mesh, (child: Mesh) => {\n child.castShadow = SceneProcessor.matchesAny(\n child.name,\n options.castShadowMeshNames,\n );\n child.receiveShadow = SceneProcessor.matchesAny(\n child.name,\n options.receiveShadowMeshNames,\n );\n });\n\n return container.children;\n }\n\n private static matchesAny(value: string, patterns: IPattern[] = []): boolean {\n return patterns.some((p) =>\n typeof p === \"string\" ? value === p : p.test(value),\n );\n }\n}\n","import {\n Box3,\n DirectionalLight,\n RGBAFormat,\n Spherical,\n Texture,\n Vector3,\n} from \"three\";\n\nexport class Sun extends DirectionalLight {\n private tempVector3D0 = new Vector3();\n private tempVector3D1 = new Vector3();\n private tempVector3D2 = new Vector3();\n private tempVector3D3 = new Vector3();\n private tempVector3D4 = new Vector3();\n private tempVector3D5 = new Vector3();\n private tempVector3D6 = new Vector3();\n private tempVector3D7 = new Vector3();\n\n private tempBox3 = new Box3();\n private tempSpherical = new Spherical();\n\n public get distance(): number {\n return this.position.length();\n }\n\n public get elevation(): number {\n return this.tempSpherical.setFromVector3(this.position).phi;\n }\n\n public get azimuth(): number {\n return this.tempSpherical.setFromVector3(this.position).theta;\n }\n\n public set distance(value: number) {\n this.tempSpherical.setFromVector3(this.position);\n this.position.setFromSphericalCoords(\n value,\n this.tempSpherical.phi,\n this.tempSpherical.theta,\n );\n }\n\n public set elevation(value: number) {\n this.tempSpherical.setFromVector3(this.position);\n this.position.setFromSphericalCoords(\n this.tempSpherical.radius,\n value,\n this.tempSpherical.theta,\n );\n }\n\n public set azimuth(value: number) {\n this.tempSpherical.setFromVector3(this.position);\n this.position.setFromSphericalCoords(\n this.tempSpherical.radius,\n this.tempSpherical.phi,\n value,\n );\n }\n\n public setShadowMapFromBox3(box3: Box3): void {\n const camera = this.shadow.camera;\n\n this.target.updateWorldMatrix(true, false);\n this.lookAt(this.target.getWorldPosition(this.tempVector3D0));\n\n this.updateWorldMatrix(true, false);\n\n const points: Vector3[] = [\n this.tempVector3D0.set(box3.min.x, box3.min.y, box3.min.z),\n this.tempVector3D1.set(box3.min.x, box3.min.y, box3.max.z),\n this.tempVector3D2.set(box3.min.x, box3.max.y, box3.min.z),\n this.tempVector3D3.set(box3.min.x, box3.max.y, box3.max.z),\n this.tempVector3D4.set(box3.max.x, box3.min.y, box3.min.z),\n this.tempVector3D5.set(box3.max.x, box3.min.y, box3.max.z),\n this.tempVector3D6.set(box3.max.x, box3.max.y, box3.min.z),\n this.tempVector3D7.set(box3.max.x, box3.max.y, box3.max.z),\n ];\n\n const inverseMatrix = this.matrixWorld.clone().invert();\n\n for (const point of points) {\n point.applyMatrix4(inverseMatrix);\n }\n\n const newBox3 = this.tempBox3.setFromPoints(points);\n\n camera.left = newBox3.min.x;\n camera.bottom = newBox3.min.y;\n camera.near = -newBox3.max.z;\n\n camera.right = newBox3.max.x;\n camera.top = newBox3.max.y;\n camera.far = -newBox3.min.z;\n\n camera.updateWorldMatrix(true, false);\n camera.updateProjectionMatrix();\n }\n\n public setDirectionFromHDR(texture: Texture, distance = 1): void {\n const data = texture.image.data;\n const width = texture.image.width;\n const height = texture.image.height;\n\n let maxLuminance = 0;\n let maxIndex = 0;\n\n const step = texture.format === RGBAFormat ? 4 : 3;\n for (let i = 0; i < data.length; i += step) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;\n if (luminance > maxLuminance) {\n maxLuminance = luminance;\n maxIndex = i;\n }\n }\n\n const pixelIndex = maxIndex / step;\n const x = pixelIndex % width;\n const y = Math.floor(pixelIndex / width);\n\n const u = x / width;\n const v = y / height;\n\n const elevation = v * Math.PI;\n const azimuth = u * -Math.PI * 2 - Math.PI / 2;\n\n this.position.setFromSphericalCoords(distance, elevation, azimuth);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/Bounds.ts","../src/Enumerator.ts","../src/GeometryComparator.ts","../src/InstanceAssembler.ts","../src/SceneProcessor.ts","../src/SkinnedMeshBaker.ts","../src/Sun.ts"],"sourcesContent":["import { Box3, Vector3 } from \"three\";\n\nexport class Bounds extends Box3 {\n private readonly tempVector3: Vector3 = new Vector3();\n\n public get width(): number {\n return this.max.x - this.min.x;\n }\n\n public get height(): number {\n return this.max.y - this.min.y;\n }\n\n public get depth(): number {\n return this.max.z - this.min.z;\n }\n\n public get diagonal(): number {\n this.tempVector3.subVectors(this.max, this.min);\n return this.tempVector3.length();\n }\n}\n","import { Material, Mesh, Object3D } from \"three\";\n\ntype Constructor<T> = abstract new (...args: never[]) => T;\n\nexport class Enumerator {\n public static getObjectByName(\n object: Object3D,\n name: string,\n ): Object3D | null {\n if (object.name === name) return object;\n\n for (const child of object.children) {\n const result = Enumerator.getObjectByName(child, name);\n if (result) return result;\n }\n\n return null;\n }\n\n public static getMaterialByName(\n object: Object3D,\n name: string,\n ): Material | null {\n if (object instanceof Mesh) {\n if (Array.isArray(object.material)) {\n for (const material of object.material) {\n if (material.name === name) return material;\n }\n } else if (object.material.name === name) {\n return object.material;\n }\n }\n\n for (const child of object.children) {\n const material = Enumerator.getMaterialByName(child, name);\n if (material) return material;\n }\n\n return null;\n }\n\n public static enumerateObjectsByType<T>(\n object: Object3D,\n type: Constructor<T>,\n callback: (instance: T) => void,\n ): void {\n if (object instanceof type) {\n callback(object);\n }\n\n for (const child of object.children) {\n Enumerator.enumerateObjectsByType(child, type, callback);\n }\n }\n\n public static enumerateMaterials(\n object: Object3D,\n callback: (material: Material) => void,\n ): void {\n if (object instanceof Mesh) {\n if (Array.isArray(object.material)) {\n for (const material of object.material) {\n callback(material);\n }\n } else {\n callback(object.material);\n }\n }\n\n for (const child of object.children) {\n Enumerator.enumerateMaterials(child, callback);\n }\n }\n\n public static setShadowRecursive(\n object: Object3D,\n castShadow = true,\n receiveShadow = true,\n ): void {\n if (object instanceof Mesh || \"isMesh\" in object) {\n (object as Mesh).castShadow = castShadow;\n (object as Mesh).receiveShadow = receiveShadow;\n }\n\n for (const child of object.children) {\n Enumerator.setShadowRecursive(child, castShadow, receiveShadow);\n }\n }\n}\n","import {\n BufferAttribute,\n BufferGeometry,\n InterleavedBufferAttribute,\n} from \"three\";\n\ntype AnySuitableAttribute = BufferAttribute | InterleavedBufferAttribute;\n\n/**\n * Utility class for comparing and hashing BufferGeometry instances with tolerance support.\n */\nexport class GeometryComparator {\n /**\n * Generates a consistent hash for a BufferGeometry based on its contents and tolerance.\n *\n * @param geometry - The geometry to hash\n * @param tolerance - Precision level for number comparison (values within tolerance are considered equal)\n * @returns A string hash that will be identical for geometrically equivalent geometries\n */\n public static getGeometryHash(\n geometry: BufferGeometry,\n tolerance = 1e-6,\n ): string {\n const hashParts: string[] = [];\n\n // Process attributes\n const attributes = geometry.attributes;\n const attributeNames = Object.keys(attributes).sort(); // Sort for consistent order\n\n for (const name of attributeNames) {\n const attribute = attributes[name] as AnySuitableAttribute;\n hashParts.push(\n `${name}:${attribute.itemSize}:${this.getAttributeHash(attribute, tolerance)}`,\n );\n }\n\n // Process index if present\n if (geometry.index) {\n hashParts.push(\n `index:${this.getAttributeHash(geometry.index, tolerance)}`,\n );\n }\n\n return hashParts.join(\"|\");\n }\n\n /**\n * Compares two BufferGeometry instances for approximate equality.\n * Early exit if UUIDs match (same object or cloned geometry).\n */\n public static compare(\n firstGeometry: BufferGeometry,\n secondGeometry: BufferGeometry,\n tolerance = 1e-6,\n ): boolean {\n if (firstGeometry.uuid === secondGeometry.uuid) {\n return true;\n }\n\n // Use hash comparison for consistent results\n return (\n this.getGeometryHash(firstGeometry, tolerance) ===\n this.getGeometryHash(secondGeometry, tolerance)\n );\n }\n\n /**\n * Generates a hash for a buffer attribute with tolerance.\n */\n private static getAttributeHash(\n attribute: AnySuitableAttribute,\n tolerance: number,\n ): string {\n const array = attribute.array;\n const itemSize = \"itemSize\" in attribute ? attribute.itemSize : 1;\n const hashParts: string[] = [];\n\n // Group values by their \"tolerance buckets\"\n for (let i = 0; i < array.length; i += itemSize) {\n const itemValues = [];\n for (let j = 0; j < itemSize; j++) {\n const val = array[i + j];\n // Round to nearest tolerance multiple to group similar values\n itemValues.push(Math.round(val / tolerance) * tolerance);\n }\n hashParts.push(itemValues.join(\",\"));\n }\n\n return hashParts.join(\";\");\n }\n\n /**\n * Compares two buffer attributes with tolerance.\n */\n private static compareBufferAttributes(\n firstAttribute: AnySuitableAttribute,\n secondAttribute: AnySuitableAttribute,\n tolerance: number,\n ): boolean {\n return (\n this.getAttributeHash(firstAttribute, tolerance) ===\n this.getAttributeHash(secondAttribute, tolerance)\n );\n }\n}\n\n// import {\n// BufferAttribute,\n// BufferGeometry,\n// InterleavedBufferAttribute,\n// } from \"three\";\n\n// type AnySuitableAttribute = BufferAttribute | InterleavedBufferAttribute;\n\n// /**\n// * Utility class for comparing two BufferGeometry instances with tolerance support.\n// * Checks geometry attributes (positions, normals, UVs, etc.) and indices (if present).\n// */\n// export class GeometryComparator {\n// /**\n// * Compares two BufferGeometry instances for approximate equality.\n// * Early exit if UUIDs match (same object or cloned geometry).\n// *\n// * @param firstGeometry - The first geometry to compare.\n// * @param secondGeometry - The second geometry to compare.\n// * @param tolerance - Maximum allowed difference between numeric values (default: 1e-6).\n// * @returns `true` if geometries are equivalent within tolerance, otherwise `false`.\n// */\n// public static compare(\n// firstGeometry: BufferGeometry,\n// secondGeometry: BufferGeometry,\n// tolerance = 1e-6,\n// ): boolean {\n// if (firstGeometry.uuid === secondGeometry.uuid) {\n// return true;\n// }\n\n// const firstAttributes = firstGeometry.attributes;\n// const secondAttributes = secondGeometry.attributes;\n\n// const firstAttributeNames = Object.keys(firstAttributes);\n// const secondAttributeNames = Object.keys(secondAttributes);\n\n// if (firstAttributeNames.length !== secondAttributeNames.length) {\n// return false;\n// }\n\n// for (const attributeName of firstAttributeNames) {\n// if (!secondAttributes[attributeName]) {\n// return false;\n// }\n\n// const firstAttribute = firstAttributes[\n// attributeName\n// ] as AnySuitableAttribute;\n// const secondAttribute = secondAttributes[\n// attributeName\n// ] as AnySuitableAttribute;\n\n// if (\n// firstAttribute.count !== secondAttribute.count ||\n// firstAttribute.itemSize !== secondAttribute.itemSize ||\n// !this.compareBufferAttributes(\n// firstAttribute,\n// secondAttribute,\n// tolerance,\n// )\n// ) {\n// return false;\n// }\n// }\n\n// if (firstGeometry.index || secondGeometry.index) {\n// if (!firstGeometry.index || !secondGeometry.index) {\n// return false;\n// }\n\n// if (\n// !this.compareBufferAttributes(\n// firstGeometry.index,\n// secondGeometry.index,\n// tolerance,\n// )\n// ) {\n// return false;\n// }\n// }\n\n// return true;\n// }\n\n// /**\n// * Compares two buffer attributes (or index buffers) with tolerance.\n// *\n// * @param firstAttribute - First attribute/indices to compare.\n// * @param secondAttribute - Second attribute/indices to compare.\n// * @param tolerance - Maximum allowed difference between array elements.\n// * @returns `true` if arrays are equal within tolerance, otherwise `false`.\n// */\n// private static compareBufferAttributes(\n// firstAttribute: AnySuitableAttribute,\n// secondAttribute: AnySuitableAttribute,\n// tolerance: number,\n// ): boolean {\n// const firstArray = firstAttribute.array;\n// const secondArray = secondAttribute.array;\n\n// if (firstArray.length !== secondArray.length) {\n// return false;\n// }\n\n// for (let index = 0; index < firstArray.length; index++) {\n// if (Math.abs(firstArray[index] - secondArray[index]) > tolerance) {\n// return false;\n// }\n// }\n\n// return true;\n// }\n// }\n","import { InstancedMesh, Material, Mesh, Object3D } from \"three\";\nimport { Enumerator } from \"./Enumerator\";\nimport { GeometryComparator } from \"./GeometryComparator\";\n\ninterface IMeshDescriptor {\n meshes: Mesh[];\n materials: Material[];\n castShadow: boolean;\n receiveShadow: boolean;\n}\n\ninterface IOptions {\n container: Object3D;\n filter?: (child: Mesh) => boolean;\n geometryTolerance?: number;\n}\n\nexport class InstanceAssembler {\n public static assemble(options: IOptions): void {\n const dictionary = new Map<string, IMeshDescriptor>();\n const instancedMeshes: InstancedMesh[] = [];\n const tolerance = options.geometryTolerance ?? 1e-6;\n const geometryHashCache = new Map<string, string>();\n\n Enumerator.enumerateObjectsByType(\n options.container,\n Mesh,\n (child: Mesh) => {\n if (\n child.children.length === 0 &&\n (!options.filter || options.filter(child))\n ) {\n const materials = Array.isArray(child.material)\n ? child.material\n : [child.material];\n\n let geometryHash = geometryHashCache.get(child.geometry.uuid);\n if (!geometryHash) {\n geometryHash = GeometryComparator.getGeometryHash(\n child.geometry,\n tolerance,\n );\n geometryHashCache.set(child.geometry.uuid, geometryHash);\n }\n\n const materialKey = materials.map((m) => m.uuid).join(\",\");\n const compositeKey = `${geometryHash}|${materialKey}`;\n\n const entry = dictionary.get(compositeKey) ?? {\n meshes: [],\n materials: materials,\n castShadow: false,\n receiveShadow: false,\n };\n\n if (child.castShadow) entry.castShadow = true;\n if (child.receiveShadow) entry.receiveShadow = true;\n\n entry.meshes.push(child);\n dictionary.set(compositeKey, entry);\n }\n },\n );\n\n for (const descriptor of dictionary.values()) {\n if (descriptor.meshes.length < 2) continue;\n const { meshes, materials, castShadow, receiveShadow } = descriptor;\n\n const sortedMeshes = meshes.sort((a, b) => a.name.localeCompare(b.name));\n const defaultMesh = sortedMeshes[0];\n\n const instancedMesh = new InstancedMesh(\n defaultMesh.geometry,\n materials.length === 1 ? materials[0] : materials,\n sortedMeshes.length,\n );\n\n instancedMesh.name = defaultMesh.name;\n instancedMesh.castShadow = castShadow;\n instancedMesh.receiveShadow = receiveShadow;\n\n for (let i = 0; i < sortedMeshes.length; i++) {\n const mesh = sortedMeshes[i];\n mesh.updateWorldMatrix(true, false);\n instancedMesh.setMatrixAt(i, mesh.matrixWorld);\n instancedMesh.userData[mesh.uuid] = mesh.userData;\n }\n\n instancedMesh.instanceMatrix.needsUpdate = true;\n instancedMeshes.push(instancedMesh);\n\n for (const mesh of sortedMeshes) {\n mesh.parent?.remove(mesh);\n }\n }\n\n if (instancedMeshes.length > 0) {\n options.container.add(...instancedMeshes);\n }\n }\n}\n","import { FrontSide, Material, Mesh, Object3D } from \"three\";\nimport { Enumerator } from \"./Enumerator\";\nimport { InstanceAssembler } from \"./InstanceAssembler\";\n\ntype IPattern = string | RegExp;\n\ninterface IOptions {\n asset: Object3D;\n castShadowMeshNames?: IPattern[];\n receiveShadowMeshNames?: IPattern[];\n transparentMaterialNames?: IPattern[];\n noDepthWriteMaterialNames?: IPattern[];\n}\n\nexport class SceneProcessor {\n public static process(options: IOptions): Object3D[] {\n const container = options.asset.clone();\n InstanceAssembler.assemble({ container: container });\n\n Enumerator.enumerateMaterials(container, (material: Material) => {\n material.transparent = SceneProcessor.matchesAny(\n material.name,\n options.transparentMaterialNames,\n );\n material.depthWrite = !SceneProcessor.matchesAny(\n material.name,\n options.noDepthWriteMaterialNames,\n );\n material.side = FrontSide;\n material.forceSinglePass = true;\n material.depthTest = true;\n });\n\n Enumerator.enumerateObjectsByType(container, Mesh, (child: Mesh) => {\n child.castShadow = SceneProcessor.matchesAny(\n child.name,\n options.castShadowMeshNames,\n );\n child.receiveShadow = SceneProcessor.matchesAny(\n child.name,\n options.receiveShadowMeshNames,\n );\n });\n\n return container.children;\n }\n\n private static matchesAny(value: string, patterns: IPattern[] = []): boolean {\n return patterns.some((p) =>\n typeof p === \"string\" ? value === p : p.test(value),\n );\n }\n}\n","import {\n AnimationClip,\n AnimationMixer,\n BufferAttribute,\n Mesh,\n Object3D,\n SkinnedMesh,\n Vector3,\n} from \"three\";\n\n/**\n * Utilities for baking poses and animations from SkinnedMesh into a regular static Mesh.\n */\nexport class SkinnedMeshBaker {\n /**\n * Bakes the current pose of a SkinnedMesh into a regular geometry.\n * Transforms all vertices according to the current skeleton state.\n *\n * @param skinnedMesh - SkinnedMesh from which to bake the geometry\n * @returns A new Mesh with positions corresponding to the current bone positions\n */\n static bakePose(skinnedMesh: SkinnedMesh): Mesh {\n const bakedGeometry = skinnedMesh.geometry.clone();\n const position = bakedGeometry.attributes[\"position\"] as BufferAttribute;\n const newPositions = new Float32Array(position.count * 3);\n const target = new Vector3();\n\n for (let i = 0; i < position.count; i++) {\n target.fromBufferAttribute(position, i);\n skinnedMesh.applyBoneTransform(i, target);\n newPositions[i * 3 + 0] = target.x;\n newPositions[i * 3 + 1] = target.y;\n newPositions[i * 3 + 2] = target.z;\n }\n\n bakedGeometry.setAttribute(\n \"position\",\n new BufferAttribute(newPositions, 3),\n );\n bakedGeometry.computeVertexNormals();\n bakedGeometry.deleteAttribute(\"skinIndex\");\n bakedGeometry.deleteAttribute(\"skinWeight\");\n\n const mesh = new Mesh(bakedGeometry, skinnedMesh.material);\n mesh.name = skinnedMesh.name;\n return mesh;\n }\n\n /**\n * Bakes a SkinnedMesh in a specific pose derived from an AnimationClip at the given timestamp.\n *\n * @param armature - The parent object (typically an armature from GLTF) containing the bones\n * @param skinnedMesh - The SkinnedMesh to be baked\n * @param timeOffset - The animation time in seconds to set\n * @param clip - The animation clip\n * @returns A new Mesh with geometry matching the specified animation frame\n */\n static bakeAnimationFrame(\n armature: Object3D,\n skinnedMesh: SkinnedMesh,\n timeOffset: number,\n clip: AnimationClip,\n ): Mesh {\n const mixer = new AnimationMixer(armature);\n const action = mixer.clipAction(clip);\n action.play();\n mixer.setTime(timeOffset);\n\n armature.updateWorldMatrix(true, true);\n skinnedMesh.skeleton.update();\n\n return this.bakePose(skinnedMesh);\n }\n}\n","import {\n Box3,\n DirectionalLight,\n RGBAFormat,\n Spherical,\n Texture,\n Vector3,\n} from \"three\";\n\nexport class Sun extends DirectionalLight {\n private tempVector3D0 = new Vector3();\n private tempVector3D1 = new Vector3();\n private tempVector3D2 = new Vector3();\n private tempVector3D3 = new Vector3();\n private tempVector3D4 = new Vector3();\n private tempVector3D5 = new Vector3();\n private tempVector3D6 = new Vector3();\n private tempVector3D7 = new Vector3();\n\n private tempBox3 = new Box3();\n private tempSpherical = new Spherical();\n\n public get distance(): number {\n return this.position.length();\n }\n\n public get elevation(): number {\n return this.tempSpherical.setFromVector3(this.position).phi;\n }\n\n public get azimuth(): number {\n return this.tempSpherical.setFromVector3(this.position).theta;\n }\n\n public set distance(value: number) {\n this.tempSpherical.setFromVector3(this.position);\n this.position.setFromSphericalCoords(\n value,\n this.tempSpherical.phi,\n this.tempSpherical.theta,\n );\n }\n\n public set elevation(value: number) {\n this.tempSpherical.setFromVector3(this.position);\n this.position.setFromSphericalCoords(\n this.tempSpherical.radius,\n value,\n this.tempSpherical.theta,\n );\n }\n\n public set azimuth(value: number) {\n this.tempSpherical.setFromVector3(this.position);\n this.position.setFromSphericalCoords(\n this.tempSpherical.radius,\n this.tempSpherical.phi,\n value,\n );\n }\n\n public setShadowMapFromBox3(box3: Box3): void {\n const camera = this.shadow.camera;\n\n this.target.updateWorldMatrix(true, false);\n this.lookAt(this.target.getWorldPosition(this.tempVector3D0));\n\n this.updateWorldMatrix(true, false);\n\n const points: Vector3[] = [\n this.tempVector3D0.set(box3.min.x, box3.min.y, box3.min.z),\n this.tempVector3D1.set(box3.min.x, box3.min.y, box3.max.z),\n this.tempVector3D2.set(box3.min.x, box3.max.y, box3.min.z),\n this.tempVector3D3.set(box3.min.x, box3.max.y, box3.max.z),\n this.tempVector3D4.set(box3.max.x, box3.min.y, box3.min.z),\n this.tempVector3D5.set(box3.max.x, box3.min.y, box3.max.z),\n this.tempVector3D6.set(box3.max.x, box3.max.y, box3.min.z),\n this.tempVector3D7.set(box3.max.x, box3.max.y, box3.max.z),\n ];\n\n const inverseMatrix = this.matrixWorld.clone().invert();\n\n for (const point of points) {\n point.applyMatrix4(inverseMatrix);\n }\n\n const newBox3 = this.tempBox3.setFromPoints(points);\n\n camera.left = newBox3.min.x;\n camera.bottom = newBox3.min.y;\n camera.near = -newBox3.max.z;\n\n camera.right = newBox3.max.x;\n camera.top = newBox3.max.y;\n camera.far = -newBox3.min.z;\n\n camera.updateWorldMatrix(true, false);\n camera.updateProjectionMatrix();\n }\n\n public setDirectionFromHDR(texture: Texture, distance = 1): void {\n const data = texture.image.data;\n const width = texture.image.width;\n const height = texture.image.height;\n\n let maxLuminance = 0;\n let maxIndex = 0;\n\n const step = texture.format === RGBAFormat ? 4 : 3;\n for (let i = 0; i < data.length; i += step) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;\n if (luminance > maxLuminance) {\n maxLuminance = luminance;\n maxIndex = i;\n }\n }\n\n const pixelIndex = maxIndex / step;\n const x = pixelIndex % width;\n const y = Math.floor(pixelIndex / width);\n\n const u = x / width;\n const v = y / height;\n\n const elevation = v * Math.PI;\n const azimuth = u * -Math.PI * 2 - Math.PI / 2;\n\n this.position.setFromSphericalCoords(distance, elevation, azimuth);\n }\n}\n"],"names":[],"mappings":"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"}
|