three-zoo 0.4.0 → 0.4.2

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.
@@ -0,0 +1,71 @@
1
+ import { PerspectiveCamera } from "three";
2
+ /**
3
+ * BiFovCamera - A specialized PerspectiveCamera that supports independent horizontal and vertical FOV settings
4
+ *
5
+ * This camera extends Three.js PerspectiveCamera to provide better control over the field of view,
6
+ * allowing separate horizontal and vertical FOV values. The camera automatically adjusts its projection
7
+ * matrix based on the aspect ratio to maintain proper perspective.
8
+ *
9
+ * @extends PerspectiveCamera
10
+ */
11
+ export declare class BiFovCamera extends PerspectiveCamera {
12
+ private horizontalFovInternal;
13
+ private verticalFovInternal;
14
+ /**
15
+ * Creates a new BiFovCamera instance
16
+ *
17
+ * @param horizontalFov - Horizontal field of view in degrees (default: 90)
18
+ * @param verticalFov - Vertical field of view in degrees (default: 90)
19
+ * @param aspect - Aspect ratio (width/height) of the viewport (default: 1)
20
+ * @param near - Near clipping plane distance (default: 1)
21
+ * @param far - Far clipping plane distance (default: 1000)
22
+ */
23
+ constructor(horizontalFov?: number, verticalFov?: number, aspect?: number, near?: number, far?: number);
24
+ /**
25
+ * Gets the horizontal field of view in degrees
26
+ */
27
+ get horizontalFov(): number;
28
+ /**
29
+ * Gets the vertical field of view in degrees
30
+ */
31
+ get verticalFov(): number;
32
+ /**
33
+ * Sets the horizontal field of view in degrees
34
+ * @param value - The new horizontal FOV value
35
+ */
36
+ set horizontalFov(value: number);
37
+ /**
38
+ * Sets the vertical field of view in degrees
39
+ * @param value - The new vertical FOV value
40
+ */
41
+ set verticalFov(value: number);
42
+ /**
43
+ * Updates both horizontal and vertical FOV simultaneously
44
+ * @param horizontal - New horizontal FOV in degrees
45
+ * @param vertical - New vertical FOV in degrees
46
+ */
47
+ setFov(horizontal: number, vertical: number): void;
48
+ /**
49
+ * Copies FOV settings from another BiFovCamera
50
+ * @param source - The camera to copy settings from
51
+ */
52
+ copyFovSettings(source: BiFovCamera): void;
53
+ /**
54
+ * Updates the projection matrix based on current FOV settings and aspect ratio
55
+ * For aspect ratios >= 1 (landscape), horizontal FOV is preserved
56
+ * For aspect ratios < 1 (portrait), vertical FOV is preserved
57
+ */
58
+ updateProjectionMatrix(): void;
59
+ /**
60
+ * Returns the actual horizontal FOV after aspect ratio adjustments
61
+ */
62
+ getEffectiveHorizontalFov(): number;
63
+ /**
64
+ * Returns the actual vertical FOV after aspect ratio adjustments
65
+ */
66
+ getEffectiveVerticalFov(): number;
67
+ /**
68
+ * Creates a clone of this camera with the same properties
69
+ */
70
+ clone(): this;
71
+ }
package/dist/Bounds.d.ts CHANGED
@@ -1,8 +1,28 @@
1
1
  import { Box3 } from "three";
2
2
  export declare class Bounds extends Box3 {
3
- private readonly tempVector3;
3
+ private readonly tempVector3A;
4
+ /**
5
+ * Gets the width (x-axis length) of the bounding box
6
+ */
4
7
  get width(): number;
8
+ /**
9
+ * Gets the height (y-axis length) of the bounding box
10
+ */
5
11
  get height(): number;
12
+ /**
13
+ * Gets the depth (z-axis length) of the bounding box
14
+ */
6
15
  get depth(): number;
16
+ /**
17
+ * Gets the length of the box's diagonal
18
+ */
7
19
  get diagonal(): number;
20
+ /**
21
+ * Gets the volume of the bounding box
22
+ */
23
+ getVolume(): number;
24
+ /**
25
+ * Gets the surface area of the bounding box
26
+ */
27
+ getSurfaceArea(): number;
8
28
  }
@@ -1,8 +1,8 @@
1
- import { BufferGeometry } from "three";
1
+ import type { BufferGeometry } from "three";
2
2
  /**
3
3
  * Utility class for comparing and hashing BufferGeometry instances with tolerance support.
4
4
  */
5
- export declare class GeometryComparator {
5
+ export declare class GeometryHasher {
6
6
  /**
7
7
  * Generates a consistent hash for a BufferGeometry based on its contents and tolerance.
8
8
  *
@@ -1,4 +1,5 @@
1
- import { Mesh, Object3D } from "three";
1
+ import type { Object3D } from "three";
2
+ import { Mesh } from "three";
2
3
  interface IOptions {
3
4
  container: Object3D;
4
5
  filter?: (child: Mesh) => boolean;
@@ -1,4 +1,4 @@
1
- import { Object3D } from "three";
1
+ import type { Object3D } from "three";
2
2
  type IPattern = string | RegExp;
3
3
  interface IOptions {
4
4
  asset: Object3D;
@@ -1,6 +1,6 @@
1
- import { Material, Object3D } from "three";
1
+ import type { Material, Object3D } from "three";
2
2
  type Constructor<T> = abstract new (...args: never[]) => T;
3
- export declare class Enumerator {
3
+ export declare class SceneTraversal {
4
4
  static getObjectByName(object: Object3D, name: string): Object3D | null;
5
5
  static getMaterialByName(object: Object3D, name: string): Material | null;
6
6
  static enumerateObjectsByType<T>(object: Object3D, type: Constructor<T>, callback: (instance: T) => void): void;
@@ -1,4 +1,5 @@
1
- import { AnimationClip, Mesh, Object3D, SkinnedMesh } from "three";
1
+ import type { AnimationClip, Object3D, SkinnedMesh } from "three";
2
+ import { Mesh } from "three";
2
3
  /**
3
4
  * Utilities for baking poses and animations from SkinnedMesh into a regular static Mesh.
4
5
  */
package/dist/Sun.d.ts CHANGED
@@ -1,21 +1,71 @@
1
- import { Box3, DirectionalLight, Texture } from "three";
1
+ import type { Texture } from "three";
2
+ import { Box3, DirectionalLight } from "three";
3
+ /**
4
+ * Sun extends Three.js DirectionalLight to provide a specialized light source that simulates
5
+ * sunlight with advanced positioning and shadow controls.
6
+ *
7
+ * Features:
8
+ * - Spherical coordinate control (distance, elevation, azimuth)
9
+ * - Automatic shadow map configuration based on bounding boxes
10
+ * - HDR environment map-based positioning
11
+ * - Efficient temporary vector management for calculations
12
+ *
13
+ * @extends DirectionalLight
14
+ */
2
15
  export declare class Sun extends DirectionalLight {
3
- private tempVector3D0;
4
- private tempVector3D1;
5
- private tempVector3D2;
6
- private tempVector3D3;
7
- private tempVector3D4;
8
- private tempVector3D5;
9
- private tempVector3D6;
10
- private tempVector3D7;
11
- private tempBox3;
12
- private tempSpherical;
16
+ private readonly tempVector3D0;
17
+ private readonly tempVector3D1;
18
+ private readonly tempVector3D2;
19
+ private readonly tempVector3D3;
20
+ private readonly tempVector3D4;
21
+ private readonly tempVector3D5;
22
+ private readonly tempVector3D6;
23
+ private readonly tempVector3D7;
24
+ private readonly tempBox3;
25
+ private readonly tempSpherical;
26
+ /**
27
+ * Gets the distance of the sun from its target (radius in spherical coordinates)
28
+ * @returns The distance in world units
29
+ */
13
30
  get distance(): number;
31
+ /**
32
+ * Gets the elevation angle of the sun (phi in spherical coordinates)
33
+ * @returns The elevation in radians
34
+ */
14
35
  get elevation(): number;
36
+ /**
37
+ * Gets the azimuth angle of the sun (theta in spherical coordinates)
38
+ * @returns The azimuth in radians
39
+ */
15
40
  get azimuth(): number;
41
+ /**
42
+ * Sets the distance of the sun from its target while maintaining current angles
43
+ * @param value - The new distance in world units
44
+ */
16
45
  set distance(value: number);
46
+ /**
47
+ * Sets the elevation angle of the sun while maintaining current distance and azimuth
48
+ * @param value - The new elevation in radians
49
+ */
17
50
  set elevation(value: number);
51
+ /**
52
+ * Sets the azimuth angle of the sun while maintaining current distance and elevation
53
+ * @param value - The new azimuth in radians
54
+ */
18
55
  set azimuth(value: number);
56
+ /**
57
+ * Configures the shadow camera's frustum to encompass the given bounding box
58
+ * This ensures that shadows are cast correctly for objects within the box
59
+ *
60
+ * @param box3 - The bounding box to configure shadows for
61
+ */
19
62
  setShadowMapFromBox3(box3: Box3): void;
63
+ /**
64
+ * Sets the sun's direction based on the brightest point in an HDR texture
65
+ * This is useful for matching the sun's position to an environment map
66
+ *
67
+ * @param texture - The HDR texture to analyze (must be loaded and have valid image data)
68
+ * @param distance - Optional distance to position the sun from its target (default: 1)
69
+ */
20
70
  setDirectionFromHDR(texture: Texture, distance?: number): void;
21
71
  }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
+ export * from "./BiFovCamera";
1
2
  export * from "./Bounds";
2
- export * from "./Enumerator";
3
3
  export * from "./InstanceAssembler";
4
4
  export * from "./SceneProcessor";
5
+ export * from "./SceneTraversal";
5
6
  export * from "./SkinnedMeshBaker";
6
7
  export * from "./Sun";
package/dist/index.js CHANGED
@@ -1,33 +1,254 @@
1
- import { Box3, Vector3, Mesh, InstancedMesh, FrontSide, BufferAttribute, AnimationMixer, DirectionalLight, Spherical, RGBAFormat } from 'three';
1
+ import { PerspectiveCamera, MathUtils, Box3, Vector3, Mesh, InstancedMesh, FrontSide, BufferAttribute, AnimationMixer, DirectionalLight, Spherical, RGBAFormat } from 'three';
2
+
3
+ /**
4
+ * Default camera settings
5
+ */
6
+ const DEFAULT_HORIZONTAL_FOV = 90;
7
+ const DEFAULT_VERTICAL_FOV = 90;
8
+ const DEFAULT_ASPECT = 1;
9
+ const DEFAULT_NEAR = 1;
10
+ const DEFAULT_FAR = 1000;
11
+ /**
12
+ * BiFovCamera - A specialized PerspectiveCamera that supports independent horizontal and vertical FOV settings
13
+ *
14
+ * This camera extends Three.js PerspectiveCamera to provide better control over the field of view,
15
+ * allowing separate horizontal and vertical FOV values. The camera automatically adjusts its projection
16
+ * matrix based on the aspect ratio to maintain proper perspective.
17
+ *
18
+ * @extends PerspectiveCamera
19
+ */
20
+ class BiFovCamera extends PerspectiveCamera {
21
+ /**
22
+ * Creates a new BiFovCamera instance
23
+ *
24
+ * @param horizontalFov - Horizontal field of view in degrees (default: 90)
25
+ * @param verticalFov - Vertical field of view in degrees (default: 90)
26
+ * @param aspect - Aspect ratio (width/height) of the viewport (default: 1)
27
+ * @param near - Near clipping plane distance (default: 1)
28
+ * @param far - Far clipping plane distance (default: 1000)
29
+ */
30
+ constructor(horizontalFov = DEFAULT_HORIZONTAL_FOV, verticalFov = DEFAULT_VERTICAL_FOV, aspect = DEFAULT_ASPECT, near = DEFAULT_NEAR, far = DEFAULT_FAR) {
31
+ super(verticalFov, aspect, near, far);
32
+ this.horizontalFovInternal = horizontalFov;
33
+ this.verticalFovInternal = verticalFov;
34
+ this.updateProjectionMatrix();
35
+ }
36
+ /**
37
+ * Gets the horizontal field of view in degrees
38
+ */
39
+ get horizontalFov() {
40
+ return this.horizontalFovInternal;
41
+ }
42
+ /**
43
+ * Gets the vertical field of view in degrees
44
+ */
45
+ get verticalFov() {
46
+ return this.verticalFovInternal;
47
+ }
48
+ /**
49
+ * Sets the horizontal field of view in degrees
50
+ * @param value - The new horizontal FOV value
51
+ */
52
+ set horizontalFov(value) {
53
+ this.horizontalFovInternal = MathUtils.clamp(value, 1, 179);
54
+ this.updateProjectionMatrix();
55
+ }
56
+ /**
57
+ * Sets the vertical field of view in degrees
58
+ * @param value - The new vertical FOV value
59
+ */
60
+ set verticalFov(value) {
61
+ this.verticalFovInternal = MathUtils.clamp(value, 1, 179);
62
+ this.updateProjectionMatrix();
63
+ }
64
+ /**
65
+ * Updates both horizontal and vertical FOV simultaneously
66
+ * @param horizontal - New horizontal FOV in degrees
67
+ * @param vertical - New vertical FOV in degrees
68
+ */
69
+ setFov(horizontal, vertical) {
70
+ this.horizontalFovInternal = MathUtils.clamp(horizontal, 1, 179);
71
+ this.verticalFovInternal = MathUtils.clamp(vertical, 1, 179);
72
+ this.updateProjectionMatrix();
73
+ }
74
+ /**
75
+ * Copies FOV settings from another BiFovCamera
76
+ * @param source - The camera to copy settings from
77
+ */
78
+ copyFovSettings(source) {
79
+ this.horizontalFovInternal = source.horizontalFov;
80
+ this.verticalFovInternal = source.verticalFov;
81
+ this.updateProjectionMatrix();
82
+ }
83
+ /**
84
+ * Updates the projection matrix based on current FOV settings and aspect ratio
85
+ * For aspect ratios >= 1 (landscape), horizontal FOV is preserved
86
+ * For aspect ratios < 1 (portrait), vertical FOV is preserved
87
+ */
88
+ updateProjectionMatrix() {
89
+ if (this.aspect >= 1) {
90
+ // Landscape orientation: preserve horizontal FOV
91
+ const radians = MathUtils.degToRad(this.horizontalFovInternal);
92
+ this.fov = MathUtils.radToDeg(Math.atan(Math.tan(radians / 2) / this.aspect) * 2);
93
+ }
94
+ else {
95
+ // Portrait orientation: preserve vertical FOV
96
+ this.fov = this.verticalFovInternal;
97
+ }
98
+ super.updateProjectionMatrix();
99
+ }
100
+ /**
101
+ * Returns the actual horizontal FOV after aspect ratio adjustments
102
+ */
103
+ getEffectiveHorizontalFov() {
104
+ if (this.aspect >= 1) {
105
+ return this.horizontalFovInternal;
106
+ }
107
+ const verticalRadians = MathUtils.degToRad(this.verticalFovInternal);
108
+ return MathUtils.radToDeg(Math.atan(Math.tan(verticalRadians / 2) * this.aspect) * 2);
109
+ }
110
+ /**
111
+ * Returns the actual vertical FOV after aspect ratio adjustments
112
+ */
113
+ getEffectiveVerticalFov() {
114
+ if (this.aspect < 1) {
115
+ return this.verticalFovInternal;
116
+ }
117
+ const horizontalRadians = MathUtils.degToRad(this.horizontalFovInternal);
118
+ return MathUtils.radToDeg(Math.atan(Math.tan(horizontalRadians / 2) / this.aspect) * 2);
119
+ }
120
+ /**
121
+ * Creates a clone of this camera with the same properties
122
+ */
123
+ clone() {
124
+ const camera = new BiFovCamera(this.horizontalFovInternal, this.verticalFovInternal, this.aspect, this.near, this.far);
125
+ camera.copy(this, true);
126
+ return camera;
127
+ }
128
+ }
2
129
 
3
130
  class Bounds extends Box3 {
4
131
  constructor() {
5
132
  super(...arguments);
6
- this.tempVector3 = new Vector3();
133
+ this.tempVector3A = new Vector3();
7
134
  }
135
+ /**
136
+ * Gets the width (x-axis length) of the bounding box
137
+ */
8
138
  get width() {
9
139
  return this.max.x - this.min.x;
10
140
  }
141
+ /**
142
+ * Gets the height (y-axis length) of the bounding box
143
+ */
11
144
  get height() {
12
145
  return this.max.y - this.min.y;
13
146
  }
147
+ /**
148
+ * Gets the depth (z-axis length) of the bounding box
149
+ */
14
150
  get depth() {
15
151
  return this.max.z - this.min.z;
16
152
  }
153
+ /**
154
+ * Gets the length of the box's diagonal
155
+ */
17
156
  get diagonal() {
18
- this.tempVector3.subVectors(this.max, this.min);
19
- return this.tempVector3.length();
157
+ return this.tempVector3A.subVectors(this.max, this.min).length();
158
+ }
159
+ /**
160
+ * Gets the volume of the bounding box
161
+ */
162
+ getVolume() {
163
+ return this.width * this.height * this.depth;
164
+ }
165
+ /**
166
+ * Gets the surface area of the bounding box
167
+ */
168
+ getSurfaceArea() {
169
+ const w = this.width;
170
+ const h = this.height;
171
+ const d = this.depth;
172
+ return 2 * (w * h + h * d + d * w);
20
173
  }
21
174
  }
22
175
 
23
- class Enumerator {
176
+ /**
177
+ * Utility class for comparing and hashing BufferGeometry instances with tolerance support.
178
+ */
179
+ class GeometryHasher {
180
+ /**
181
+ * Generates a consistent hash for a BufferGeometry based on its contents and tolerance.
182
+ *
183
+ * @param geometry - The geometry to hash
184
+ * @param tolerance - Precision level for number comparison (values within tolerance are considered equal)
185
+ * @returns A string hash that will be identical for geometrically equivalent geometries
186
+ */
187
+ static getGeometryHash(geometry, tolerance = 1e-6) {
188
+ const hashParts = [];
189
+ // Process attributes
190
+ const attributes = geometry.attributes;
191
+ const attributeNames = Object.keys(attributes).sort(); // Sort for consistent order
192
+ for (const name of attributeNames) {
193
+ const attribute = attributes[name];
194
+ hashParts.push(`${name}:${attribute.itemSize}:${this.getAttributeHash(attribute, tolerance)}`);
195
+ }
196
+ // Process index if present
197
+ if (geometry.index) {
198
+ hashParts.push(`index:${this.getAttributeHash(geometry.index, tolerance)}`);
199
+ }
200
+ return hashParts.join("|");
201
+ }
202
+ /**
203
+ * Compares two BufferGeometry instances for approximate equality.
204
+ * Early exit if UUIDs match (same object or cloned geometry).
205
+ */
206
+ static compare(firstGeometry, secondGeometry, tolerance = 1e-6) {
207
+ if (firstGeometry.uuid === secondGeometry.uuid) {
208
+ return true;
209
+ }
210
+ // Use hash comparison for consistent results
211
+ return (this.getGeometryHash(firstGeometry, tolerance) ===
212
+ this.getGeometryHash(secondGeometry, tolerance));
213
+ }
214
+ /**
215
+ * Generates a hash for a buffer attribute with tolerance.
216
+ */
217
+ static getAttributeHash(attribute, tolerance) {
218
+ const array = attribute.array;
219
+ const itemSize = "itemSize" in attribute ? attribute.itemSize : 1;
220
+ const hashParts = [];
221
+ // Group values by their "tolerance buckets"
222
+ for (let i = 0; i < array.length; i += itemSize) {
223
+ const itemValues = [];
224
+ for (let j = 0; j < itemSize; j++) {
225
+ const val = array[i + j];
226
+ // Round to nearest tolerance multiple to group similar values
227
+ itemValues.push(Math.round(val / tolerance) * tolerance);
228
+ }
229
+ hashParts.push(itemValues.join(","));
230
+ }
231
+ return hashParts.join(";");
232
+ }
233
+ /**
234
+ * Compares two buffer attributes with tolerance.
235
+ */
236
+ static compareBufferAttributes(firstAttribute, secondAttribute, tolerance) {
237
+ return (this.getAttributeHash(firstAttribute, tolerance) ===
238
+ this.getAttributeHash(secondAttribute, tolerance));
239
+ }
240
+ }
241
+
242
+ class SceneTraversal {
24
243
  static getObjectByName(object, name) {
25
- if (object.name === name)
244
+ if (object.name === name) {
26
245
  return object;
246
+ }
27
247
  for (const child of object.children) {
28
- const result = Enumerator.getObjectByName(child, name);
29
- if (result)
248
+ const result = SceneTraversal.getObjectByName(child, name);
249
+ if (result) {
30
250
  return result;
251
+ }
31
252
  }
32
253
  return null;
33
254
  }
@@ -35,8 +256,9 @@ class Enumerator {
35
256
  if (object instanceof Mesh) {
36
257
  if (Array.isArray(object.material)) {
37
258
  for (const material of object.material) {
38
- if (material.name === name)
259
+ if (material.name === name) {
39
260
  return material;
261
+ }
40
262
  }
41
263
  }
42
264
  else if (object.material.name === name) {
@@ -44,9 +266,10 @@ class Enumerator {
44
266
  }
45
267
  }
46
268
  for (const child of object.children) {
47
- const material = Enumerator.getMaterialByName(child, name);
48
- if (material)
269
+ const material = SceneTraversal.getMaterialByName(child, name);
270
+ if (material) {
49
271
  return material;
272
+ }
50
273
  }
51
274
  return null;
52
275
  }
@@ -55,7 +278,7 @@ class Enumerator {
55
278
  callback(object);
56
279
  }
57
280
  for (const child of object.children) {
58
- Enumerator.enumerateObjectsByType(child, type, callback);
281
+ SceneTraversal.enumerateObjectsByType(child, type, callback);
59
282
  }
60
283
  }
61
284
  static enumerateMaterials(object, callback) {
@@ -70,7 +293,7 @@ class Enumerator {
70
293
  }
71
294
  }
72
295
  for (const child of object.children) {
73
- Enumerator.enumerateMaterials(child, callback);
296
+ SceneTraversal.enumerateMaterials(child, callback);
74
297
  }
75
298
  }
76
299
  static filterObjects(object, name) {
@@ -79,7 +302,7 @@ class Enumerator {
79
302
  result.push(object);
80
303
  }
81
304
  for (const child of object.children) {
82
- result = result.concat(Enumerator.filterObjects(child, name));
305
+ result = result.concat(SceneTraversal.filterObjects(child, name));
83
306
  }
84
307
  return result;
85
308
  }
@@ -100,7 +323,7 @@ class Enumerator {
100
323
  }
101
324
  }
102
325
  for (const child of object.children) {
103
- result = result.concat(Enumerator.filterMaterials(child, name));
326
+ result = result.concat(SceneTraversal.filterMaterials(child, name));
104
327
  }
105
328
  return result;
106
329
  }
@@ -110,176 +333,11 @@ class Enumerator {
110
333
  object.receiveShadow = receiveShadow;
111
334
  }
112
335
  for (const child of object.children) {
113
- Enumerator.setShadowRecursive(child, castShadow, receiveShadow);
336
+ SceneTraversal.setShadowRecursive(child, castShadow, receiveShadow);
114
337
  }
115
338
  }
116
339
  }
117
340
 
118
- /**
119
- * Utility class for comparing and hashing BufferGeometry instances with tolerance support.
120
- */
121
- class GeometryComparator {
122
- /**
123
- * Generates a consistent hash for a BufferGeometry based on its contents and tolerance.
124
- *
125
- * @param geometry - The geometry to hash
126
- * @param tolerance - Precision level for number comparison (values within tolerance are considered equal)
127
- * @returns A string hash that will be identical for geometrically equivalent geometries
128
- */
129
- static getGeometryHash(geometry, tolerance = 1e-6) {
130
- const hashParts = [];
131
- // Process attributes
132
- const attributes = geometry.attributes;
133
- const attributeNames = Object.keys(attributes).sort(); // Sort for consistent order
134
- for (const name of attributeNames) {
135
- const attribute = attributes[name];
136
- hashParts.push(`${name}:${attribute.itemSize}:${this.getAttributeHash(attribute, tolerance)}`);
137
- }
138
- // Process index if present
139
- if (geometry.index) {
140
- hashParts.push(`index:${this.getAttributeHash(geometry.index, tolerance)}`);
141
- }
142
- return hashParts.join("|");
143
- }
144
- /**
145
- * Compares two BufferGeometry instances for approximate equality.
146
- * Early exit if UUIDs match (same object or cloned geometry).
147
- */
148
- static compare(firstGeometry, secondGeometry, tolerance = 1e-6) {
149
- if (firstGeometry.uuid === secondGeometry.uuid) {
150
- return true;
151
- }
152
- // Use hash comparison for consistent results
153
- return (this.getGeometryHash(firstGeometry, tolerance) ===
154
- this.getGeometryHash(secondGeometry, tolerance));
155
- }
156
- /**
157
- * Generates a hash for a buffer attribute with tolerance.
158
- */
159
- static getAttributeHash(attribute, tolerance) {
160
- const array = attribute.array;
161
- const itemSize = "itemSize" in attribute ? attribute.itemSize : 1;
162
- const hashParts = [];
163
- // Group values by their "tolerance buckets"
164
- for (let i = 0; i < array.length; i += itemSize) {
165
- const itemValues = [];
166
- for (let j = 0; j < itemSize; j++) {
167
- const val = array[i + j];
168
- // Round to nearest tolerance multiple to group similar values
169
- itemValues.push(Math.round(val / tolerance) * tolerance);
170
- }
171
- hashParts.push(itemValues.join(","));
172
- }
173
- return hashParts.join(";");
174
- }
175
- /**
176
- * Compares two buffer attributes with tolerance.
177
- */
178
- static compareBufferAttributes(firstAttribute, secondAttribute, tolerance) {
179
- return (this.getAttributeHash(firstAttribute, tolerance) ===
180
- this.getAttributeHash(secondAttribute, tolerance));
181
- }
182
- }
183
- // import {
184
- // BufferAttribute,
185
- // BufferGeometry,
186
- // InterleavedBufferAttribute,
187
- // } from "three";
188
- // type AnySuitableAttribute = BufferAttribute | InterleavedBufferAttribute;
189
- // /**
190
- // * Utility class for comparing two BufferGeometry instances with tolerance support.
191
- // * Checks geometry attributes (positions, normals, UVs, etc.) and indices (if present).
192
- // */
193
- // export class GeometryComparator {
194
- // /**
195
- // * Compares two BufferGeometry instances for approximate equality.
196
- // * Early exit if UUIDs match (same object or cloned geometry).
197
- // *
198
- // * @param firstGeometry - The first geometry to compare.
199
- // * @param secondGeometry - The second geometry to compare.
200
- // * @param tolerance - Maximum allowed difference between numeric values (default: 1e-6).
201
- // * @returns `true` if geometries are equivalent within tolerance, otherwise `false`.
202
- // */
203
- // public static compare(
204
- // firstGeometry: BufferGeometry,
205
- // secondGeometry: BufferGeometry,
206
- // tolerance = 1e-6,
207
- // ): boolean {
208
- // if (firstGeometry.uuid === secondGeometry.uuid) {
209
- // return true;
210
- // }
211
- // const firstAttributes = firstGeometry.attributes;
212
- // const secondAttributes = secondGeometry.attributes;
213
- // const firstAttributeNames = Object.keys(firstAttributes);
214
- // const secondAttributeNames = Object.keys(secondAttributes);
215
- // if (firstAttributeNames.length !== secondAttributeNames.length) {
216
- // return false;
217
- // }
218
- // for (const attributeName of firstAttributeNames) {
219
- // if (!secondAttributes[attributeName]) {
220
- // return false;
221
- // }
222
- // const firstAttribute = firstAttributes[
223
- // attributeName
224
- // ] as AnySuitableAttribute;
225
- // const secondAttribute = secondAttributes[
226
- // attributeName
227
- // ] as AnySuitableAttribute;
228
- // if (
229
- // firstAttribute.count !== secondAttribute.count ||
230
- // firstAttribute.itemSize !== secondAttribute.itemSize ||
231
- // !this.compareBufferAttributes(
232
- // firstAttribute,
233
- // secondAttribute,
234
- // tolerance,
235
- // )
236
- // ) {
237
- // return false;
238
- // }
239
- // }
240
- // if (firstGeometry.index || secondGeometry.index) {
241
- // if (!firstGeometry.index || !secondGeometry.index) {
242
- // return false;
243
- // }
244
- // if (
245
- // !this.compareBufferAttributes(
246
- // firstGeometry.index,
247
- // secondGeometry.index,
248
- // tolerance,
249
- // )
250
- // ) {
251
- // return false;
252
- // }
253
- // }
254
- // return true;
255
- // }
256
- // /**
257
- // * Compares two buffer attributes (or index buffers) with tolerance.
258
- // *
259
- // * @param firstAttribute - First attribute/indices to compare.
260
- // * @param secondAttribute - Second attribute/indices to compare.
261
- // * @param tolerance - Maximum allowed difference between array elements.
262
- // * @returns `true` if arrays are equal within tolerance, otherwise `false`.
263
- // */
264
- // private static compareBufferAttributes(
265
- // firstAttribute: AnySuitableAttribute,
266
- // secondAttribute: AnySuitableAttribute,
267
- // tolerance: number,
268
- // ): boolean {
269
- // const firstArray = firstAttribute.array;
270
- // const secondArray = secondAttribute.array;
271
- // if (firstArray.length !== secondArray.length) {
272
- // return false;
273
- // }
274
- // for (let index = 0; index < firstArray.length; index++) {
275
- // if (Math.abs(firstArray[index] - secondArray[index]) > tolerance) {
276
- // return false;
277
- // }
278
- // }
279
- // return true;
280
- // }
281
- // }
282
-
283
341
  class InstanceAssembler {
284
342
  static assemble(options) {
285
343
  var _a, _b;
@@ -287,7 +345,7 @@ class InstanceAssembler {
287
345
  const instancedMeshes = [];
288
346
  const tolerance = (_a = options.geometryTolerance) !== null && _a !== void 0 ? _a : 1e-6;
289
347
  const geometryHashCache = new Map();
290
- Enumerator.enumerateObjectsByType(options.container, Mesh, (child) => {
348
+ SceneTraversal.enumerateObjectsByType(options.container, Mesh, (child) => {
291
349
  var _a;
292
350
  if (child.children.length === 0 &&
293
351
  (!options.filter || options.filter(child))) {
@@ -296,7 +354,7 @@ class InstanceAssembler {
296
354
  : [child.material];
297
355
  let geometryHash = geometryHashCache.get(child.geometry.uuid);
298
356
  if (!geometryHash) {
299
- geometryHash = GeometryComparator.getGeometryHash(child.geometry, tolerance);
357
+ geometryHash = GeometryHasher.getGeometryHash(child.geometry, tolerance);
300
358
  geometryHashCache.set(child.geometry.uuid, geometryHash);
301
359
  }
302
360
  const materialKey = materials.map((m) => m.uuid).join(",");
@@ -307,17 +365,20 @@ class InstanceAssembler {
307
365
  castShadow: false,
308
366
  receiveShadow: false,
309
367
  };
310
- if (child.castShadow)
368
+ if (child.castShadow) {
311
369
  entry.castShadow = true;
312
- if (child.receiveShadow)
370
+ }
371
+ if (child.receiveShadow) {
313
372
  entry.receiveShadow = true;
373
+ }
314
374
  entry.meshes.push(child);
315
375
  dictionary.set(compositeKey, entry);
316
376
  }
317
377
  });
318
378
  for (const descriptor of dictionary.values()) {
319
- if (descriptor.meshes.length < 2)
379
+ if (descriptor.meshes.length < 2) {
320
380
  continue;
381
+ }
321
382
  const { meshes, materials, castShadow, receiveShadow } = descriptor;
322
383
  const sortedMeshes = meshes.sort((a, b) => a.name.localeCompare(b.name));
323
384
  const defaultMesh = sortedMeshes[0];
@@ -347,14 +408,14 @@ class SceneProcessor {
347
408
  static process(options) {
348
409
  const container = options.asset.clone();
349
410
  InstanceAssembler.assemble({ container: container });
350
- Enumerator.enumerateMaterials(container, (material) => {
411
+ SceneTraversal.enumerateMaterials(container, (material) => {
351
412
  material.transparent = SceneProcessor.matchesAny(material.name, options.transparentMaterialNames);
352
413
  material.depthWrite = !SceneProcessor.matchesAny(material.name, options.noDepthWriteMaterialNames);
353
414
  material.side = FrontSide;
354
415
  material.forceSinglePass = true;
355
416
  material.depthTest = true;
356
417
  });
357
- Enumerator.enumerateObjectsByType(container, Mesh, (child) => {
418
+ SceneTraversal.enumerateObjectsByType(container, Mesh, (child) => {
358
419
  child.castShadow = SceneProcessor.matchesAny(child.name, options.castShadowMeshNames);
359
420
  child.receiveShadow = SceneProcessor.matchesAny(child.name, options.receiveShadowMeshNames);
360
421
  });
@@ -416,9 +477,22 @@ class SkinnedMeshBaker {
416
477
  }
417
478
  }
418
479
 
480
+ /**
481
+ * Sun extends Three.js DirectionalLight to provide a specialized light source that simulates
482
+ * sunlight with advanced positioning and shadow controls.
483
+ *
484
+ * Features:
485
+ * - Spherical coordinate control (distance, elevation, azimuth)
486
+ * - Automatic shadow map configuration based on bounding boxes
487
+ * - HDR environment map-based positioning
488
+ * - Efficient temporary vector management for calculations
489
+ *
490
+ * @extends DirectionalLight
491
+ */
419
492
  class Sun extends DirectionalLight {
420
493
  constructor() {
421
494
  super(...arguments);
495
+ // Temporary vectors for calculations to avoid garbage collection
422
496
  this.tempVector3D0 = new Vector3();
423
497
  this.tempVector3D1 = new Vector3();
424
498
  this.tempVector3D2 = new Vector3();
@@ -430,27 +504,57 @@ class Sun extends DirectionalLight {
430
504
  this.tempBox3 = new Box3();
431
505
  this.tempSpherical = new Spherical();
432
506
  }
507
+ /**
508
+ * Gets the distance of the sun from its target (radius in spherical coordinates)
509
+ * @returns The distance in world units
510
+ */
433
511
  get distance() {
434
512
  return this.position.length();
435
513
  }
514
+ /**
515
+ * Gets the elevation angle of the sun (phi in spherical coordinates)
516
+ * @returns The elevation in radians
517
+ */
436
518
  get elevation() {
437
519
  return this.tempSpherical.setFromVector3(this.position).phi;
438
520
  }
521
+ /**
522
+ * Gets the azimuth angle of the sun (theta in spherical coordinates)
523
+ * @returns The azimuth in radians
524
+ */
439
525
  get azimuth() {
440
526
  return this.tempSpherical.setFromVector3(this.position).theta;
441
527
  }
528
+ /**
529
+ * Sets the distance of the sun from its target while maintaining current angles
530
+ * @param value - The new distance in world units
531
+ */
442
532
  set distance(value) {
443
533
  this.tempSpherical.setFromVector3(this.position);
444
534
  this.position.setFromSphericalCoords(value, this.tempSpherical.phi, this.tempSpherical.theta);
445
535
  }
536
+ /**
537
+ * Sets the elevation angle of the sun while maintaining current distance and azimuth
538
+ * @param value - The new elevation in radians
539
+ */
446
540
  set elevation(value) {
447
541
  this.tempSpherical.setFromVector3(this.position);
448
542
  this.position.setFromSphericalCoords(this.tempSpherical.radius, value, this.tempSpherical.theta);
449
543
  }
544
+ /**
545
+ * Sets the azimuth angle of the sun while maintaining current distance and elevation
546
+ * @param value - The new azimuth in radians
547
+ */
450
548
  set azimuth(value) {
451
549
  this.tempSpherical.setFromVector3(this.position);
452
550
  this.position.setFromSphericalCoords(this.tempSpherical.radius, this.tempSpherical.phi, value);
453
551
  }
552
+ /**
553
+ * Configures the shadow camera's frustum to encompass the given bounding box
554
+ * This ensures that shadows are cast correctly for objects within the box
555
+ *
556
+ * @param box3 - The bounding box to configure shadows for
557
+ */
454
558
  setShadowMapFromBox3(box3) {
455
559
  const camera = this.shadow.camera;
456
560
  this.target.updateWorldMatrix(true, false);
@@ -480,23 +584,33 @@ class Sun extends DirectionalLight {
480
584
  camera.updateWorldMatrix(true, false);
481
585
  camera.updateProjectionMatrix();
482
586
  }
587
+ /**
588
+ * Sets the sun's direction based on the brightest point in an HDR texture
589
+ * This is useful for matching the sun's position to an environment map
590
+ *
591
+ * @param texture - The HDR texture to analyze (must be loaded and have valid image data)
592
+ * @param distance - Optional distance to position the sun from its target (default: 1)
593
+ */
483
594
  setDirectionFromHDR(texture, distance = 1) {
484
595
  const data = texture.image.data;
485
596
  const width = texture.image.width;
486
597
  const height = texture.image.height;
487
598
  let maxLuminance = 0;
488
599
  let maxIndex = 0;
600
+ // Find the brightest pixel in the HDR texture
489
601
  const step = texture.format === RGBAFormat ? 4 : 3;
490
602
  for (let i = 0; i < data.length; i += step) {
491
603
  const r = data[i];
492
604
  const g = data[i + 1];
493
605
  const b = data[i + 2];
606
+ // Calculate luminance using the Rec. 709 coefficients
494
607
  const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
495
608
  if (luminance > maxLuminance) {
496
609
  maxLuminance = luminance;
497
610
  maxIndex = i;
498
611
  }
499
612
  }
613
+ // Convert pixel coordinates to spherical coordinates
500
614
  const pixelIndex = maxIndex / step;
501
615
  const x = pixelIndex % width;
502
616
  const y = Math.floor(pixelIndex / width);
@@ -508,5 +622,5 @@ class Sun extends DirectionalLight {
508
622
  }
509
623
  }
510
624
 
511
- export { Bounds, Enumerator, InstanceAssembler, SceneProcessor, SkinnedMeshBaker, Sun };
625
+ export { BiFovCamera, Bounds, InstanceAssembler, SceneProcessor, SceneTraversal, SkinnedMeshBaker, Sun };
512
626
  //# 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/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 filterObjects(object: Object3D, name: RegExp): Object3D[] {\n let result: Object3D[] = [];\n\n if (object.name && name.test(object.name)) {\n result.push(object);\n }\n\n for (const child of object.children) {\n result = result.concat(Enumerator.filterObjects(child, name));\n }\n\n return result;\n }\n\n public static filterMaterials(object: Object3D, name: RegExp): Material[] {\n let result: Material[] = [];\n\n if (object instanceof Mesh) {\n if (Array.isArray(object.material)) {\n for (const material of object.material) {\n if (material.name && name.test(material.name)) {\n result.push(material);\n }\n }\n } else {\n if (object.material.name && name.test(object.material.name)) {\n result.push(object.material);\n }\n }\n }\n\n for (const child of object.children) {\n result = result.concat(Enumerator.filterMaterials(child, name));\n }\n\n return result;\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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"}
1
+ {"version":3,"file":"index.js","sources":["../src/BiFovCamera.ts","../src/Bounds.ts","../src/GeometryHasher.ts","../src/SceneTraversal.ts","../src/InstanceAssembler.ts","../src/SceneProcessor.ts","../src/SkinnedMeshBaker.ts","../src/Sun.ts"],"sourcesContent":["import { MathUtils, PerspectiveCamera } from \"three\";\n\n/**\n * Default camera settings\n */\nconst DEFAULT_HORIZONTAL_FOV = 90;\nconst DEFAULT_VERTICAL_FOV = 90;\nconst DEFAULT_ASPECT = 1;\nconst DEFAULT_NEAR = 1;\nconst DEFAULT_FAR = 1000;\n\n/**\n * BiFovCamera - A specialized PerspectiveCamera that supports independent horizontal and vertical FOV settings\n *\n * This camera extends Three.js PerspectiveCamera to provide better control over the field of view,\n * allowing separate horizontal and vertical FOV values. The camera automatically adjusts its projection\n * matrix based on the aspect ratio to maintain proper perspective.\n *\n * @extends PerspectiveCamera\n */\nexport class BiFovCamera extends PerspectiveCamera {\n private horizontalFovInternal: number;\n private verticalFovInternal: number;\n\n /**\n * Creates a new BiFovCamera instance\n *\n * @param horizontalFov - Horizontal field of view in degrees (default: 90)\n * @param verticalFov - Vertical field of view in degrees (default: 90)\n * @param aspect - Aspect ratio (width/height) of the viewport (default: 1)\n * @param near - Near clipping plane distance (default: 1)\n * @param far - Far clipping plane distance (default: 1000)\n */\n constructor(\n horizontalFov = DEFAULT_HORIZONTAL_FOV,\n verticalFov = DEFAULT_VERTICAL_FOV,\n aspect = DEFAULT_ASPECT,\n near = DEFAULT_NEAR,\n far = DEFAULT_FAR,\n ) {\n super(verticalFov, aspect, near, far);\n this.horizontalFovInternal = horizontalFov;\n this.verticalFovInternal = verticalFov;\n this.updateProjectionMatrix();\n }\n\n /**\n * Gets the horizontal field of view in degrees\n */\n public get horizontalFov(): number {\n return this.horizontalFovInternal;\n }\n\n /**\n * Gets the vertical field of view in degrees\n */\n public get verticalFov(): number {\n return this.verticalFovInternal;\n }\n\n /**\n * Sets the horizontal field of view in degrees\n * @param value - The new horizontal FOV value\n */\n public set horizontalFov(value: number) {\n this.horizontalFovInternal = MathUtils.clamp(value, 1, 179);\n this.updateProjectionMatrix();\n }\n\n /**\n * Sets the vertical field of view in degrees\n * @param value - The new vertical FOV value\n */\n public set verticalFov(value: number) {\n this.verticalFovInternal = MathUtils.clamp(value, 1, 179);\n this.updateProjectionMatrix();\n }\n\n /**\n * Updates both horizontal and vertical FOV simultaneously\n * @param horizontal - New horizontal FOV in degrees\n * @param vertical - New vertical FOV in degrees\n */\n public setFov(horizontal: number, vertical: number): void {\n this.horizontalFovInternal = MathUtils.clamp(horizontal, 1, 179);\n this.verticalFovInternal = MathUtils.clamp(vertical, 1, 179);\n this.updateProjectionMatrix();\n }\n\n /**\n * Copies FOV settings from another BiFovCamera\n * @param source - The camera to copy settings from\n */\n public copyFovSettings(source: BiFovCamera): void {\n this.horizontalFovInternal = source.horizontalFov;\n this.verticalFovInternal = source.verticalFov;\n this.updateProjectionMatrix();\n }\n\n /**\n * Updates the projection matrix based on current FOV settings and aspect ratio\n * For aspect ratios >= 1 (landscape), horizontal FOV is preserved\n * For aspect ratios < 1 (portrait), vertical FOV is preserved\n */\n public override updateProjectionMatrix(): void {\n if (this.aspect >= 1) {\n // Landscape orientation: preserve horizontal FOV\n const radians = MathUtils.degToRad(this.horizontalFovInternal);\n this.fov = MathUtils.radToDeg(\n Math.atan(Math.tan(radians / 2) / this.aspect) * 2,\n );\n } else {\n // Portrait orientation: preserve vertical FOV\n this.fov = this.verticalFovInternal;\n }\n\n super.updateProjectionMatrix();\n }\n\n /**\n * Returns the actual horizontal FOV after aspect ratio adjustments\n */\n public getEffectiveHorizontalFov(): number {\n if (this.aspect >= 1) {\n return this.horizontalFovInternal;\n }\n const verticalRadians = MathUtils.degToRad(this.verticalFovInternal);\n return MathUtils.radToDeg(\n Math.atan(Math.tan(verticalRadians / 2) * this.aspect) * 2,\n );\n }\n\n /**\n * Returns the actual vertical FOV after aspect ratio adjustments\n */\n public getEffectiveVerticalFov(): number {\n if (this.aspect < 1) {\n return this.verticalFovInternal;\n }\n const horizontalRadians = MathUtils.degToRad(this.horizontalFovInternal);\n return MathUtils.radToDeg(\n Math.atan(Math.tan(horizontalRadians / 2) / this.aspect) * 2,\n );\n }\n\n /**\n * Creates a clone of this camera with the same properties\n */\n public override clone(): this {\n const camera = new BiFovCamera(\n this.horizontalFovInternal,\n this.verticalFovInternal,\n this.aspect,\n this.near,\n this.far,\n ) as this;\n\n camera.copy(this, true);\n return camera;\n }\n}\n","import { Box3, Vector3 } from \"three\";\n\nexport class Bounds extends Box3 {\n private readonly tempVector3A: Vector3 = new Vector3();\n\n /**\n * Gets the width (x-axis length) of the bounding box\n */\n public get width(): number {\n return this.max.x - this.min.x;\n }\n\n /**\n * Gets the height (y-axis length) of the bounding box\n */\n public get height(): number {\n return this.max.y - this.min.y;\n }\n\n /**\n * Gets the depth (z-axis length) of the bounding box\n */\n public get depth(): number {\n return this.max.z - this.min.z;\n }\n\n /**\n * Gets the length of the box's diagonal\n */\n public get diagonal(): number {\n return this.tempVector3A.subVectors(this.max, this.min).length();\n }\n\n /**\n * Gets the volume of the bounding box\n */\n public getVolume(): number {\n return this.width * this.height * this.depth;\n }\n\n /**\n * Gets the surface area of the bounding box\n */\n public getSurfaceArea(): number {\n const w = this.width;\n const h = this.height;\n const d = this.depth;\n return 2 * (w * h + h * d + d * w);\n }\n}\n","import type {\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 GeometryHasher {\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","import type { Material, Object3D } from \"three\";\nimport { Mesh } from \"three\";\n\ntype Constructor<T> = abstract new (...args: never[]) => T;\n\nexport class SceneTraversal {\n public static getObjectByName(\n object: Object3D,\n name: string,\n ): Object3D | null {\n if (object.name === name) {\n return object;\n }\n\n for (const child of object.children) {\n const result = SceneTraversal.getObjectByName(child, name);\n if (result) {\n return result;\n }\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) {\n return material;\n }\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 = SceneTraversal.getMaterialByName(child, name);\n if (material) {\n return material;\n }\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 SceneTraversal.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 SceneTraversal.enumerateMaterials(child, callback);\n }\n }\n\n public static filterObjects(object: Object3D, name: RegExp): Object3D[] {\n let result: Object3D[] = [];\n\n if (object.name && name.test(object.name)) {\n result.push(object);\n }\n\n for (const child of object.children) {\n result = result.concat(SceneTraversal.filterObjects(child, name));\n }\n\n return result;\n }\n\n public static filterMaterials(object: Object3D, name: RegExp): Material[] {\n let result: Material[] = [];\n\n if (object instanceof Mesh) {\n if (Array.isArray(object.material)) {\n for (const material of object.material) {\n if (material.name && name.test(material.name)) {\n result.push(material);\n }\n }\n } else {\n if (object.material.name && name.test(object.material.name)) {\n result.push(object.material);\n }\n }\n }\n\n for (const child of object.children) {\n result = result.concat(SceneTraversal.filterMaterials(child, name));\n }\n\n return result;\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 SceneTraversal.setShadowRecursive(child, castShadow, receiveShadow);\n }\n }\n}\n","import type { Material, Object3D } from \"three\";\nimport { InstancedMesh, Mesh } from \"three\";\nimport { GeometryHasher } from \"./GeometryHasher\";\nimport { SceneTraversal } from \"./SceneTraversal\";\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 SceneTraversal.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 = GeometryHasher.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) {\n entry.castShadow = true;\n }\n if (child.receiveShadow) {\n entry.receiveShadow = true;\n }\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) {\n continue;\n }\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 type { Material, Object3D } from \"three\";\nimport { FrontSide, Mesh } from \"three\";\nimport { InstanceAssembler } from \"./InstanceAssembler\";\nimport { SceneTraversal } from \"./SceneTraversal\";\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 SceneTraversal.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 SceneTraversal.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 type { AnimationClip, Object3D, SkinnedMesh } from \"three\";\nimport { AnimationMixer, BufferAttribute, Mesh, Vector3 } 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 public 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 public 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 type { Texture } from \"three\";\nimport { Box3, DirectionalLight, RGBAFormat, Spherical, Vector3 } from \"three\";\n\n/**\n * Sun extends Three.js DirectionalLight to provide a specialized light source that simulates\n * sunlight with advanced positioning and shadow controls.\n * \n * Features:\n * - Spherical coordinate control (distance, elevation, azimuth)\n * - Automatic shadow map configuration based on bounding boxes\n * - HDR environment map-based positioning\n * - Efficient temporary vector management for calculations\n * \n * @extends DirectionalLight\n */\nexport class Sun extends DirectionalLight {\n // Temporary vectors for calculations to avoid garbage collection\n private readonly tempVector3D0 = new Vector3();\n private readonly tempVector3D1 = new Vector3();\n private readonly tempVector3D2 = new Vector3();\n private readonly tempVector3D3 = new Vector3();\n private readonly tempVector3D4 = new Vector3();\n private readonly tempVector3D5 = new Vector3();\n private readonly tempVector3D6 = new Vector3();\n private readonly tempVector3D7 = new Vector3();\n\n private readonly tempBox3 = new Box3();\n private readonly tempSpherical = new Spherical();\n\n /**\n * Gets the distance of the sun from its target (radius in spherical coordinates)\n * @returns The distance in world units\n */\n public get distance(): number {\n return this.position.length();\n }\n\n /**\n * Gets the elevation angle of the sun (phi in spherical coordinates)\n * @returns The elevation in radians\n */\n public get elevation(): number {\n return this.tempSpherical.setFromVector3(this.position).phi;\n }\n\n /**\n * Gets the azimuth angle of the sun (theta in spherical coordinates)\n * @returns The azimuth in radians\n */\n public get azimuth(): number {\n return this.tempSpherical.setFromVector3(this.position).theta;\n }\n\n /**\n * Sets the distance of the sun from its target while maintaining current angles\n * @param value - The new distance in world units\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 /**\n * Sets the elevation angle of the sun while maintaining current distance and azimuth\n * @param value - The new elevation in radians\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 /**\n * Sets the azimuth angle of the sun while maintaining current distance and elevation\n * @param value - The new azimuth in radians\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 /**\n * Configures the shadow camera's frustum to encompass the given bounding box\n * This ensures that shadows are cast correctly for objects within the box\n * \n * @param box3 - The bounding box to configure shadows for\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 /**\n * Sets the sun's direction based on the brightest point in an HDR texture\n * This is useful for matching the sun's position to an environment map\n * \n * @param texture - The HDR texture to analyze (must be loaded and have valid image data)\n * @param distance - Optional distance to position the sun from its target (default: 1)\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 // Find the brightest pixel in the HDR texture\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 // Calculate luminance using the Rec. 709 coefficients\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 // Convert pixel coordinates to spherical coordinates\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}"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{PerspectiveCamera as t,MathUtils as s,Box3 as e,Vector3 as i,Mesh as r,InstancedMesh as n,FrontSide as h,BufferAttribute as o,AnimationMixer as c,DirectionalLight as a,Spherical as f,RGBAFormat as u}from"three";class l extends t{constructor(t=90,s=90,e=1,i=1,r=1e3){super(s,e,i,r),this.horizontalFovInternal=t,this.verticalFovInternal=s,this.updateProjectionMatrix()}get horizontalFov(){return this.horizontalFovInternal}get verticalFov(){return this.verticalFovInternal}set horizontalFov(t){this.horizontalFovInternal=s.clamp(t,1,179),this.updateProjectionMatrix()}set verticalFov(t){this.verticalFovInternal=s.clamp(t,1,179),this.updateProjectionMatrix()}setFov(t,e){this.horizontalFovInternal=s.clamp(t,1,179),this.verticalFovInternal=s.clamp(e,1,179),this.updateProjectionMatrix()}copyFovSettings(t){this.horizontalFovInternal=t.horizontalFov,this.verticalFovInternal=t.verticalFov,this.updateProjectionMatrix()}updateProjectionMatrix(){if(this.aspect>=1){const t=s.degToRad(this.horizontalFovInternal);this.fov=s.radToDeg(2*Math.atan(Math.tan(t/2)/this.aspect))}else this.fov=this.verticalFovInternal;super.updateProjectionMatrix()}getEffectiveHorizontalFov(){if(this.aspect>=1)return this.horizontalFovInternal;const t=s.degToRad(this.verticalFovInternal);return s.radToDeg(2*Math.atan(Math.tan(t/2)*this.aspect))}getEffectiveVerticalFov(){if(this.aspect<1)return this.verticalFovInternal;const t=s.degToRad(this.horizontalFovInternal);return s.radToDeg(2*Math.atan(Math.tan(t/2)/this.aspect))}clone(){const t=new l(this.horizontalFovInternal,this.verticalFovInternal,this.aspect,this.near,this.far);return t.copy(this,!0),t}}class w extends e{constructor(){super(...arguments),this.tempVector3A=new i}get width(){return this.max.x-this.min.x}get height(){return this.max.y-this.min.y}get depth(){return this.max.z-this.min.z}get diagonal(){return this.tempVector3A.subVectors(this.max,this.min).length()}getVolume(){return this.width*this.height*this.depth}getSurfaceArea(){const t=this.width,s=this.height,e=this.depth;return 2*(t*s+s*e+e*t)}}class m{static getGeometryHash(t,s=1e-6){const e=[],i=t.attributes,r=Object.keys(i).sort();for(const t of r){const r=i[t];e.push(`${t}:${r.itemSize}:${this.getAttributeHash(r,s)}`)}return t.index&&e.push("index:"+this.getAttributeHash(t.index,s)),e.join("|")}static compare(t,s,e=1e-6){return t.uuid===s.uuid||this.getGeometryHash(t,e)===this.getGeometryHash(s,e)}static getAttributeHash(t,s){const e=t.array,i="itemSize"in t?t.itemSize:1,r=[];for(let t=0;t<e.length;t+=i){const n=[];for(let r=0;r<i;r++)n.push(Math.round(e[t+r]/s)*s);r.push(n.join(","))}return r.join(";")}static compareBufferAttributes(t,s,e){return this.getAttributeHash(t,e)===this.getAttributeHash(s,e)}}class g{static getObjectByName(t,s){if(t.name===s)return t;for(const e of t.children){const t=g.getObjectByName(e,s);if(t)return t}return null}static getMaterialByName(t,s){if(t instanceof r)if(Array.isArray(t.material)){for(const e of t.material)if(e.name===s)return e}else if(t.material.name===s)return t.material;for(const e of t.children){const t=g.getMaterialByName(e,s);if(t)return t}return null}static enumerateObjectsByType(t,s,e){t instanceof s&&e(t);for(const i of t.children)g.enumerateObjectsByType(i,s,e)}static enumerateMaterials(t,s){if(t instanceof r)if(Array.isArray(t.material))for(const e of t.material)s(e);else s(t.material);for(const e of t.children)g.enumerateMaterials(e,s)}static filterObjects(t,s){let e=[];t.name&&s.test(t.name)&&e.push(t);for(const i of t.children)e=e.concat(g.filterObjects(i,s));return e}static filterMaterials(t,s){let e=[];if(t instanceof r)if(Array.isArray(t.material))for(const i of t.material)i.name&&s.test(i.name)&&e.push(i);else t.material.name&&s.test(t.material.name)&&e.push(t.material);for(const i of t.children)e=e.concat(g.filterMaterials(i,s));return e}static setShadowRecursive(t,s=!0,e=!0){(t instanceof r||"isMesh"in t)&&(t.castShadow=s,t.receiveShadow=e);for(const i of t.children)g.setShadowRecursive(i,s,e)}}class v{static assemble(t){var s,e;const i=new Map,h=[],o=null!==(s=t.geometryTolerance)&&void 0!==s?s:1e-6,c=new Map;g.enumerateObjectsByType(t.container,r,(s=>{var e;if(0===s.children.length&&(!t.filter||t.filter(s))){const t=Array.isArray(s.material)?s.material:[s.material];let r=c.get(s.geometry.uuid);r||(r=m.getGeometryHash(s.geometry,o),c.set(s.geometry.uuid,r));const n=`${r}|${t.map((t=>t.uuid)).join(",")}`,h=null!==(e=i.get(n))&&void 0!==e?e:{meshes:[],materials:t,castShadow:!1,receiveShadow:!1};s.castShadow&&(h.castShadow=!0),s.receiveShadow&&(h.receiveShadow=!0),h.meshes.push(s),i.set(n,h)}}));for(const t of i.values()){if(t.meshes.length<2)continue;const{meshes:s,materials:i,castShadow:r,receiveShadow:o}=t,c=s.sort(((t,s)=>t.name.localeCompare(s.name))),a=c[0],f=new n(a.geometry,1===i.length?i[0]:i,c.length);f.name=a.name,f.castShadow=r,f.receiveShadow=o;for(let t=0;t<c.length;t++){const s=c[t];s.updateWorldMatrix(!0,!1),f.setMatrixAt(t,s.matrixWorld),f.userData[s.uuid]=s.userData}f.instanceMatrix.needsUpdate=!0,h.push(f);for(const t of c)null===(e=t.parent)||void 0===e||e.remove(t)}h.length>0&&t.container.add(...h)}}class d{static process(t){const s=t.asset.clone();return v.assemble({container:s}),g.enumerateMaterials(s,(s=>{s.transparent=d.matchesAny(s.name,t.transparentMaterialNames),s.depthWrite=!d.matchesAny(s.name,t.noDepthWriteMaterialNames),s.side=h,s.forceSinglePass=!0,s.depthTest=!0})),g.enumerateObjectsByType(s,r,(s=>{s.castShadow=d.matchesAny(s.name,t.castShadowMeshNames),s.receiveShadow=d.matchesAny(s.name,t.receiveShadowMeshNames)})),s.children}static matchesAny(t,s=[]){return s.some((s=>"string"==typeof s?t===s:s.test(t)))}}class M{static bakePose(t){const s=t.geometry.clone(),e=s.attributes.position,n=new Float32Array(3*e.count),h=new i;for(let s=0;s<e.count;s++)h.fromBufferAttribute(e,s),t.applyBoneTransform(s,h),n[3*s+0]=h.x,n[3*s+1]=h.y,n[3*s+2]=h.z;s.setAttribute("position",new o(n,3)),s.computeVertexNormals(),s.deleteAttribute("skinIndex"),s.deleteAttribute("skinWeight");const c=new r(s,t.material);return c.name=t.name,c}static bakeAnimationFrame(t,s,e,i){const r=new c(t);return r.clipAction(i).play(),r.setTime(e),t.updateWorldMatrix(!0,!0),s.skeleton.update(),this.bakePose(s)}}class p extends a{constructor(){super(...arguments),this.tempVector3D0=new i,this.tempVector3D1=new i,this.tempVector3D2=new i,this.tempVector3D3=new i,this.tempVector3D4=new i,this.tempVector3D5=new i,this.tempVector3D6=new i,this.tempVector3D7=new i,this.tempBox3=new e,this.tempSpherical=new f}get distance(){return this.position.length()}get elevation(){return this.tempSpherical.setFromVector3(this.position).phi}get azimuth(){return this.tempSpherical.setFromVector3(this.position).theta}set distance(t){this.tempSpherical.setFromVector3(this.position),this.position.setFromSphericalCoords(t,this.tempSpherical.phi,this.tempSpherical.theta)}set elevation(t){this.tempSpherical.setFromVector3(this.position),this.position.setFromSphericalCoords(this.tempSpherical.radius,t,this.tempSpherical.theta)}set azimuth(t){this.tempSpherical.setFromVector3(this.position),this.position.setFromSphericalCoords(this.tempSpherical.radius,this.tempSpherical.phi,t)}setShadowMapFromBox3(t){const s=this.shadow.camera;this.target.updateWorldMatrix(!0,!1),this.lookAt(this.target.getWorldPosition(this.tempVector3D0)),this.updateWorldMatrix(!0,!1);const e=[this.tempVector3D0.set(t.min.x,t.min.y,t.min.z),this.tempVector3D1.set(t.min.x,t.min.y,t.max.z),this.tempVector3D2.set(t.min.x,t.max.y,t.min.z),this.tempVector3D3.set(t.min.x,t.max.y,t.max.z),this.tempVector3D4.set(t.max.x,t.min.y,t.min.z),this.tempVector3D5.set(t.max.x,t.min.y,t.max.z),this.tempVector3D6.set(t.max.x,t.max.y,t.min.z),this.tempVector3D7.set(t.max.x,t.max.y,t.max.z)],i=this.matrixWorld.clone().invert();for(const t of e)t.applyMatrix4(i);const r=this.tempBox3.setFromPoints(e);s.left=r.min.x,s.bottom=r.min.y,s.near=-r.max.z,s.right=r.max.x,s.top=r.max.y,s.far=-r.min.z,s.updateWorldMatrix(!0,!1),s.updateProjectionMatrix()}setDirectionFromHDR(t,s=1){const e=t.image.data,i=t.image.width,r=t.image.height;let n=0,h=0;const o=t.format===u?4:3;for(let t=0;t<e.length;t+=o){const s=.2126*e[t]+.7152*e[t+1]+.0722*e[t+2];s>n&&(n=s,h=t)}const c=h/o,a=c%i;this.position.setFromSphericalCoords(s,Math.floor(c/i)/r*Math.PI,a/i*-Math.PI*2-Math.PI/2)}}export{l as BiFovCamera,w as Bounds,v as InstanceAssembler,d as SceneProcessor,g as SceneTraversal,M as SkinnedMeshBaker,p as Sun};
2
+ //# sourceMappingURL=index.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.min.js","sources":["../src/BiFovCamera.ts","../src/Bounds.ts","../src/GeometryHasher.ts","../src/SceneTraversal.ts","../src/InstanceAssembler.ts","../src/SceneProcessor.ts","../src/SkinnedMeshBaker.ts","../src/Sun.ts"],"sourcesContent":["import { MathUtils, PerspectiveCamera } from \"three\";\n\n/**\n * Default camera settings\n */\nconst DEFAULT_HORIZONTAL_FOV = 90;\nconst DEFAULT_VERTICAL_FOV = 90;\nconst DEFAULT_ASPECT = 1;\nconst DEFAULT_NEAR = 1;\nconst DEFAULT_FAR = 1000;\n\n/**\n * BiFovCamera - A specialized PerspectiveCamera that supports independent horizontal and vertical FOV settings\n *\n * This camera extends Three.js PerspectiveCamera to provide better control over the field of view,\n * allowing separate horizontal and vertical FOV values. The camera automatically adjusts its projection\n * matrix based on the aspect ratio to maintain proper perspective.\n *\n * @extends PerspectiveCamera\n */\nexport class BiFovCamera extends PerspectiveCamera {\n private horizontalFovInternal: number;\n private verticalFovInternal: number;\n\n /**\n * Creates a new BiFovCamera instance\n *\n * @param horizontalFov - Horizontal field of view in degrees (default: 90)\n * @param verticalFov - Vertical field of view in degrees (default: 90)\n * @param aspect - Aspect ratio (width/height) of the viewport (default: 1)\n * @param near - Near clipping plane distance (default: 1)\n * @param far - Far clipping plane distance (default: 1000)\n */\n constructor(\n horizontalFov = DEFAULT_HORIZONTAL_FOV,\n verticalFov = DEFAULT_VERTICAL_FOV,\n aspect = DEFAULT_ASPECT,\n near = DEFAULT_NEAR,\n far = DEFAULT_FAR,\n ) {\n super(verticalFov, aspect, near, far);\n this.horizontalFovInternal = horizontalFov;\n this.verticalFovInternal = verticalFov;\n this.updateProjectionMatrix();\n }\n\n /**\n * Gets the horizontal field of view in degrees\n */\n public get horizontalFov(): number {\n return this.horizontalFovInternal;\n }\n\n /**\n * Gets the vertical field of view in degrees\n */\n public get verticalFov(): number {\n return this.verticalFovInternal;\n }\n\n /**\n * Sets the horizontal field of view in degrees\n * @param value - The new horizontal FOV value\n */\n public set horizontalFov(value: number) {\n this.horizontalFovInternal = MathUtils.clamp(value, 1, 179);\n this.updateProjectionMatrix();\n }\n\n /**\n * Sets the vertical field of view in degrees\n * @param value - The new vertical FOV value\n */\n public set verticalFov(value: number) {\n this.verticalFovInternal = MathUtils.clamp(value, 1, 179);\n this.updateProjectionMatrix();\n }\n\n /**\n * Updates both horizontal and vertical FOV simultaneously\n * @param horizontal - New horizontal FOV in degrees\n * @param vertical - New vertical FOV in degrees\n */\n public setFov(horizontal: number, vertical: number): void {\n this.horizontalFovInternal = MathUtils.clamp(horizontal, 1, 179);\n this.verticalFovInternal = MathUtils.clamp(vertical, 1, 179);\n this.updateProjectionMatrix();\n }\n\n /**\n * Copies FOV settings from another BiFovCamera\n * @param source - The camera to copy settings from\n */\n public copyFovSettings(source: BiFovCamera): void {\n this.horizontalFovInternal = source.horizontalFov;\n this.verticalFovInternal = source.verticalFov;\n this.updateProjectionMatrix();\n }\n\n /**\n * Updates the projection matrix based on current FOV settings and aspect ratio\n * For aspect ratios >= 1 (landscape), horizontal FOV is preserved\n * For aspect ratios < 1 (portrait), vertical FOV is preserved\n */\n public override updateProjectionMatrix(): void {\n if (this.aspect >= 1) {\n // Landscape orientation: preserve horizontal FOV\n const radians = MathUtils.degToRad(this.horizontalFovInternal);\n this.fov = MathUtils.radToDeg(\n Math.atan(Math.tan(radians / 2) / this.aspect) * 2,\n );\n } else {\n // Portrait orientation: preserve vertical FOV\n this.fov = this.verticalFovInternal;\n }\n\n super.updateProjectionMatrix();\n }\n\n /**\n * Returns the actual horizontal FOV after aspect ratio adjustments\n */\n public getEffectiveHorizontalFov(): number {\n if (this.aspect >= 1) {\n return this.horizontalFovInternal;\n }\n const verticalRadians = MathUtils.degToRad(this.verticalFovInternal);\n return MathUtils.radToDeg(\n Math.atan(Math.tan(verticalRadians / 2) * this.aspect) * 2,\n );\n }\n\n /**\n * Returns the actual vertical FOV after aspect ratio adjustments\n */\n public getEffectiveVerticalFov(): number {\n if (this.aspect < 1) {\n return this.verticalFovInternal;\n }\n const horizontalRadians = MathUtils.degToRad(this.horizontalFovInternal);\n return MathUtils.radToDeg(\n Math.atan(Math.tan(horizontalRadians / 2) / this.aspect) * 2,\n );\n }\n\n /**\n * Creates a clone of this camera with the same properties\n */\n public override clone(): this {\n const camera = new BiFovCamera(\n this.horizontalFovInternal,\n this.verticalFovInternal,\n this.aspect,\n this.near,\n this.far,\n ) as this;\n\n camera.copy(this, true);\n return camera;\n }\n}\n","import { Box3, Vector3 } from \"three\";\n\nexport class Bounds extends Box3 {\n private readonly tempVector3A: Vector3 = new Vector3();\n\n /**\n * Gets the width (x-axis length) of the bounding box\n */\n public get width(): number {\n return this.max.x - this.min.x;\n }\n\n /**\n * Gets the height (y-axis length) of the bounding box\n */\n public get height(): number {\n return this.max.y - this.min.y;\n }\n\n /**\n * Gets the depth (z-axis length) of the bounding box\n */\n public get depth(): number {\n return this.max.z - this.min.z;\n }\n\n /**\n * Gets the length of the box's diagonal\n */\n public get diagonal(): number {\n return this.tempVector3A.subVectors(this.max, this.min).length();\n }\n\n /**\n * Gets the volume of the bounding box\n */\n public getVolume(): number {\n return this.width * this.height * this.depth;\n }\n\n /**\n * Gets the surface area of the bounding box\n */\n public getSurfaceArea(): number {\n const w = this.width;\n const h = this.height;\n const d = this.depth;\n return 2 * (w * h + h * d + d * w);\n }\n}\n","import type {\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 GeometryHasher {\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","import type { Material, Object3D } from \"three\";\nimport { Mesh } from \"three\";\n\ntype Constructor<T> = abstract new (...args: never[]) => T;\n\nexport class SceneTraversal {\n public static getObjectByName(\n object: Object3D,\n name: string,\n ): Object3D | null {\n if (object.name === name) {\n return object;\n }\n\n for (const child of object.children) {\n const result = SceneTraversal.getObjectByName(child, name);\n if (result) {\n return result;\n }\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) {\n return material;\n }\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 = SceneTraversal.getMaterialByName(child, name);\n if (material) {\n return material;\n }\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 SceneTraversal.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 SceneTraversal.enumerateMaterials(child, callback);\n }\n }\n\n public static filterObjects(object: Object3D, name: RegExp): Object3D[] {\n let result: Object3D[] = [];\n\n if (object.name && name.test(object.name)) {\n result.push(object);\n }\n\n for (const child of object.children) {\n result = result.concat(SceneTraversal.filterObjects(child, name));\n }\n\n return result;\n }\n\n public static filterMaterials(object: Object3D, name: RegExp): Material[] {\n let result: Material[] = [];\n\n if (object instanceof Mesh) {\n if (Array.isArray(object.material)) {\n for (const material of object.material) {\n if (material.name && name.test(material.name)) {\n result.push(material);\n }\n }\n } else {\n if (object.material.name && name.test(object.material.name)) {\n result.push(object.material);\n }\n }\n }\n\n for (const child of object.children) {\n result = result.concat(SceneTraversal.filterMaterials(child, name));\n }\n\n return result;\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 SceneTraversal.setShadowRecursive(child, castShadow, receiveShadow);\n }\n }\n}\n","import type { Material, Object3D } from \"three\";\nimport { InstancedMesh, Mesh } from \"three\";\nimport { GeometryHasher } from \"./GeometryHasher\";\nimport { SceneTraversal } from \"./SceneTraversal\";\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 SceneTraversal.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 = GeometryHasher.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) {\n entry.castShadow = true;\n }\n if (child.receiveShadow) {\n entry.receiveShadow = true;\n }\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) {\n continue;\n }\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 type { Material, Object3D } from \"three\";\nimport { FrontSide, Mesh } from \"three\";\nimport { InstanceAssembler } from \"./InstanceAssembler\";\nimport { SceneTraversal } from \"./SceneTraversal\";\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 SceneTraversal.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 SceneTraversal.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 type { AnimationClip, Object3D, SkinnedMesh } from \"three\";\nimport { AnimationMixer, BufferAttribute, Mesh, Vector3 } 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 public 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 public 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 type { Texture } from \"three\";\nimport { Box3, DirectionalLight, RGBAFormat, Spherical, Vector3 } from \"three\";\n\n/**\n * Sun extends Three.js DirectionalLight to provide a specialized light source that simulates\n * sunlight with advanced positioning and shadow controls.\n * \n * Features:\n * - Spherical coordinate control (distance, elevation, azimuth)\n * - Automatic shadow map configuration based on bounding boxes\n * - HDR environment map-based positioning\n * - Efficient temporary vector management for calculations\n * \n * @extends DirectionalLight\n */\nexport class Sun extends DirectionalLight {\n // Temporary vectors for calculations to avoid garbage collection\n private readonly tempVector3D0 = new Vector3();\n private readonly tempVector3D1 = new Vector3();\n private readonly tempVector3D2 = new Vector3();\n private readonly tempVector3D3 = new Vector3();\n private readonly tempVector3D4 = new Vector3();\n private readonly tempVector3D5 = new Vector3();\n private readonly tempVector3D6 = new Vector3();\n private readonly tempVector3D7 = new Vector3();\n\n private readonly tempBox3 = new Box3();\n private readonly tempSpherical = new Spherical();\n\n /**\n * Gets the distance of the sun from its target (radius in spherical coordinates)\n * @returns The distance in world units\n */\n public get distance(): number {\n return this.position.length();\n }\n\n /**\n * Gets the elevation angle of the sun (phi in spherical coordinates)\n * @returns The elevation in radians\n */\n public get elevation(): number {\n return this.tempSpherical.setFromVector3(this.position).phi;\n }\n\n /**\n * Gets the azimuth angle of the sun (theta in spherical coordinates)\n * @returns The azimuth in radians\n */\n public get azimuth(): number {\n return this.tempSpherical.setFromVector3(this.position).theta;\n }\n\n /**\n * Sets the distance of the sun from its target while maintaining current angles\n * @param value - The new distance in world units\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 /**\n * Sets the elevation angle of the sun while maintaining current distance and azimuth\n * @param value - The new elevation in radians\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 /**\n * Sets the azimuth angle of the sun while maintaining current distance and elevation\n * @param value - The new azimuth in radians\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 /**\n * Configures the shadow camera's frustum to encompass the given bounding box\n * This ensures that shadows are cast correctly for objects within the box\n * \n * @param box3 - The bounding box to configure shadows for\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 /**\n * Sets the sun's direction based on the brightest point in an HDR texture\n * This is useful for matching the sun's position to an environment map\n * \n * @param texture - The HDR texture to analyze (must be loaded and have valid image data)\n * @param distance - Optional distance to position the sun from its target (default: 1)\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 // Find the brightest pixel in the HDR texture\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 // Calculate luminance using the Rec. 709 coefficients\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 // Convert pixel coordinates to spherical coordinates\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}"],"names":["BiFovCamera","PerspectiveCamera","constructor","horizontalFov","verticalFov","aspect","near","far","super","this","horizontalFovInternal","verticalFovInternal","updateProjectionMatrix","value","MathUtils","clamp","setFov","horizontal","vertical","copyFovSettings","source","radians","degToRad","fov","radToDeg","Math","atan","tan","getEffectiveHorizontalFov","verticalRadians","getEffectiveVerticalFov","horizontalRadians","clone","camera","copy","Bounds","Box3","tempVector3A","Vector3","width","max","x","min","height","y","depth","z","diagonal","subVectors","length","getVolume","getSurfaceArea","w","h","d","GeometryHasher","getGeometryHash","geometry","tolerance","hashParts","attributes","attributeNames","Object","keys","sort","name","attribute","push","itemSize","getAttributeHash","index","join","compare","firstGeometry","secondGeometry","uuid","array","i","itemValues","j","round","compareBufferAttributes","firstAttribute","secondAttribute","SceneTraversal","getObjectByName","object","child","children","result","getMaterialByName","Mesh","Array","isArray","material","enumerateObjectsByType","type","callback","enumerateMaterials","filterObjects","test","concat","filterMaterials","setShadowRecursive","castShadow","receiveShadow","InstanceAssembler","assemble","options","dictionary","Map","instancedMeshes","_a","geometryTolerance","geometryHashCache","container","filter","materials","geometryHash","get","set","compositeKey","map","m","entry","meshes","descriptor","values","sortedMeshes","a","b","localeCompare","defaultMesh","instancedMesh","InstancedMesh","mesh","updateWorldMatrix","setMatrixAt","matrixWorld","userData","instanceMatrix","needsUpdate","_b","parent","remove","add","SceneProcessor","process","asset","transparent","matchesAny","transparentMaterialNames","depthWrite","noDepthWriteMaterialNames","side","FrontSide","forceSinglePass","depthTest","castShadowMeshNames","receiveShadowMeshNames","patterns","some","p","SkinnedMeshBaker","bakePose","skinnedMesh","bakedGeometry","position","newPositions","Float32Array","count","target","fromBufferAttribute","applyBoneTransform","setAttribute","BufferAttribute","computeVertexNormals","deleteAttribute","bakeAnimationFrame","armature","timeOffset","clip","mixer","AnimationMixer","clipAction","play","setTime","skeleton","update","Sun","DirectionalLight","tempVector3D0","tempVector3D1","tempVector3D2","tempVector3D3","tempVector3D4","tempVector3D5","tempVector3D6","tempVector3D7","tempBox3","tempSpherical","Spherical","distance","elevation","setFromVector3","phi","azimuth","theta","setFromSphericalCoords","radius","setShadowMapFromBox3","box3","shadow","lookAt","getWorldPosition","points","inverseMatrix","invert","point","applyMatrix4","newBox3","setFromPoints","left","bottom","right","top","setDirectionFromHDR","texture","data","image","maxLuminance","maxIndex","step","format","RGBAFormat","luminance","pixelIndex","floor","PI"],"mappings":"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"}
package/package.json CHANGED
@@ -1,17 +1,24 @@
1
1
  {
2
2
  "name": "three-zoo",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "zoo of tiny three js tools",
5
5
  "scripts": {
6
6
  "clean": "rm -rf dist",
7
- "build": "npm run clean && rollup -c"
7
+ "build": "npm run clean && rollup -c",
8
+ "build:prod": "npm run clean && NODE_ENV=production rollup -c",
9
+ "prepublishOnly": "npm run build:prod"
8
10
  },
9
11
  "main": "dist/index.js",
12
+ "module": "dist/index.js",
10
13
  "types": "dist/index.d.ts",
11
14
  "exports": {
12
15
  ".": {
13
- "import": "./dist/index.js",
14
- "types": "./dist/index.d.ts"
16
+ "types": "./dist/index.d.ts",
17
+ "import": {
18
+ "development": "./dist/index.js",
19
+ "production": "./dist/index.min.js",
20
+ "default": "./dist/index.min.js"
21
+ }
15
22
  }
16
23
  },
17
24
  "files": [
@@ -30,6 +37,7 @@
30
37
  },
31
38
  "devDependencies": {
32
39
  "@rollup/plugin-node-resolve": "^16.0.1",
40
+ "@rollup/plugin-terser": "^0.4.4",
33
41
  "@types/three": "^0.176.0",
34
42
  "@typescript-eslint/eslint-plugin": "^8.32.0",
35
43
  "@typescript-eslint/parser": "^8.32.0",