three-zoo 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # three-zoo
2
+
3
+ A few Three.js utilities to handle common 3D tasks.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install three-zoo
9
+ ```
10
+
11
+ ## Tools
12
+
13
+ ### BiFovCamera
14
+
15
+ Camera with separate horizontal and vertical FOV control:
16
+
17
+ ```typescript
18
+ const camera = new BiFovCamera(90, 60); // hFov, vFov
19
+ camera.horizontalFov = 100; // Change horizontal FOV
20
+ camera.verticalFov = 70; // Change vertical FOV
21
+ ```
22
+
23
+ ### Bounds
24
+
25
+ Extra bounding box calculations:
26
+
27
+ ```typescript
28
+ const bounds = new Bounds(mesh);
29
+ console.log(bounds.width); // x-axis length
30
+ console.log(bounds.depth); // z-axis length
31
+ console.log(bounds.getVolume()); // volume
32
+ ```
33
+
34
+ ### InstanceAssembler
35
+
36
+ Combines identical meshes into instances:
37
+
38
+ ```typescript
39
+ // Basic - combine all identical meshes
40
+ InstanceAssembler.assemble(scene);
41
+
42
+ // Custom - only specific meshes
43
+ InstanceAssembler.assemble(scene, {
44
+ filter: mesh => mesh.name.startsWith('Tree_'),
45
+ geometryTolerance: 0.001
46
+ });
47
+ ```
48
+
49
+ ### SceneProcessor
50
+
51
+ Sets up materials and shadows based on naming patterns:
52
+
53
+ ```typescript
54
+ SceneProcessor.process(scene, {
55
+ castShadowExpressions: [/^Tree_.*/],
56
+ receiveShadwoExpressions: [/Ground/],
57
+ transparentMaterialExpressions: [/Glass/],
58
+ });
59
+ ```
60
+
61
+ ### SceneTraversal
62
+
63
+ Scene graph utilities:
64
+
65
+ ```typescript
66
+ // Find objects
67
+ const obj = SceneTraversal.getObjectByName(scene, 'player');
68
+ const objects = SceneTraversal.filterObjects(scene, /^enemy_/);
69
+
70
+ // Configure shadows
71
+ SceneTraversal.setShadowRecursive(scene, true, true);
72
+ ```
73
+
74
+ ### SkinnedMeshBaker
75
+
76
+ Converts skinned meshes to static geometry:
77
+
78
+ ```typescript
79
+ // Bake current pose
80
+ const staticMesh = SkinnedMeshBaker.bakePose(skinnedMesh);
81
+
82
+ // Bake animation frame
83
+ const frameMesh = SkinnedMeshBaker.bakeAnimationFrame(
84
+ armature,
85
+ skinnedMesh,
86
+ 1.5, // time
87
+ clip // animation
88
+ );
89
+ ```
90
+
91
+ ### Sun
92
+
93
+ Directional light with spherical positioning:
94
+
95
+ ```typescript
96
+ const sun = new Sun();
97
+ sun.elevation = Math.PI / 4; // 45°
98
+ sun.azimuth = Math.PI / 2; // 90°
99
+
100
+ // Set up shadows
101
+ sun.setShadowMapFromBox3(new Bounds().setFromObject(scene));
102
+ ```
103
+
104
+ ## Requirements
105
+
106
+ - three >= 0.150.0
107
+
108
+ ## License
109
+
110
+ MIT
@@ -1,71 +1,49 @@
1
1
  import { PerspectiveCamera } from "three";
2
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
3
+ * A camera that supports independent horizontal and vertical FOV settings.
4
+ * Extends Three.js PerspectiveCamera to allow separate control over horizontal
5
+ * and vertical fields of view.
10
6
  */
11
7
  export declare class BiFovCamera extends PerspectiveCamera {
12
8
  private horizontalFovInternal;
13
9
  private verticalFovInternal;
14
10
  /**
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)
11
+ * @param horizontalFov - Horizontal FOV in degrees (90° default)
12
+ * @param verticalFov - Vertical FOV in degrees (90° default)
13
+ * @param aspect - Width/height ratio (1 default)
14
+ * @param near - Near clipping plane (1 default)
15
+ * @param far - Far clipping plane (1000 default)
22
16
  */
23
17
  constructor(horizontalFov?: number, verticalFov?: number, aspect?: number, near?: number, far?: number);
24
- /**
25
- * Gets the horizontal field of view in degrees
26
- */
18
+ /** Current horizontal FOV in degrees */
27
19
  get horizontalFov(): number;
28
- /**
29
- * Gets the vertical field of view in degrees
30
- */
20
+ /** Current vertical FOV in degrees */
31
21
  get verticalFov(): number;
32
- /**
33
- * Sets the horizontal field of view in degrees
34
- * @param value - The new horizontal FOV value
35
- */
22
+ /** Set horizontal FOV in degrees (clamped between 1° and 179°) */
36
23
  set horizontalFov(value: number);
37
- /**
38
- * Sets the vertical field of view in degrees
39
- * @param value - The new vertical FOV value
40
- */
24
+ /** Set vertical FOV in degrees (clamped between 1° and 179°) */
41
25
  set verticalFov(value: number);
42
26
  /**
43
- * Updates both horizontal and vertical FOV simultaneously
44
- * @param horizontal - New horizontal FOV in degrees
45
- * @param vertical - New vertical FOV in degrees
27
+ * Update both horizontal and vertical FOV
28
+ * @param horizontal - Horizontal FOV in degrees
29
+ * @param vertical - Vertical FOV in degrees
46
30
  */
47
31
  setFov(horizontal: number, vertical: number): void;
48
32
  /**
49
- * Copies FOV settings from another BiFovCamera
50
- * @param source - The camera to copy settings from
33
+ * Copy FOV settings from another BiFovCamera
34
+ * @param source - Camera to copy from
51
35
  */
52
36
  copyFovSettings(source: BiFovCamera): void;
53
37
  /**
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
38
+ * Updates the projection matrix based on FOV settings and aspect ratio.
39
+ * In landscape: preserves horizontal FOV
40
+ * In portrait: preserves vertical FOV
57
41
  */
58
42
  updateProjectionMatrix(): void;
59
- /**
60
- * Returns the actual horizontal FOV after aspect ratio adjustments
61
- */
43
+ /** Get actual horizontal FOV after aspect ratio adjustments */
62
44
  getEffectiveHorizontalFov(): number;
63
- /**
64
- * Returns the actual vertical FOV after aspect ratio adjustments
65
- */
45
+ /** Get actual vertical FOV after aspect ratio adjustments */
66
46
  getEffectiveVerticalFov(): number;
67
- /**
68
- * Creates a clone of this camera with the same properties
69
- */
47
+ /** Create a clone of this camera */
70
48
  clone(): this;
71
49
  }
package/dist/Bounds.d.ts CHANGED
@@ -1,28 +1,22 @@
1
+ import type { Object3D } from "three";
1
2
  import { Box3 } from "three";
3
+ /**
4
+ * Box3 with additional convenience methods for width, height, depth, etc.
5
+ */
2
6
  export declare class Bounds extends Box3 {
7
+ /** Temporary vector for calculations */
3
8
  private readonly tempVector3A;
4
- /**
5
- * Gets the width (x-axis length) of the bounding box
6
- */
9
+ constructor(object?: Object3D);
10
+ /** Width (x-axis length) */
7
11
  get width(): number;
8
- /**
9
- * Gets the height (y-axis length) of the bounding box
10
- */
12
+ /** Height (y-axis length) */
11
13
  get height(): number;
12
- /**
13
- * Gets the depth (z-axis length) of the bounding box
14
- */
14
+ /** Depth (z-axis length) */
15
15
  get depth(): number;
16
- /**
17
- * Gets the length of the box's diagonal
18
- */
16
+ /** Length of the box's diagonal */
19
17
  get diagonal(): number;
20
- /**
21
- * Gets the volume of the bounding box
22
- */
18
+ /** Volume (width * height * depth) */
23
19
  getVolume(): number;
24
- /**
25
- * Gets the surface area of the bounding box
26
- */
20
+ /** Surface area (sum of all six faces) */
27
21
  getSurfaceArea(): number;
28
22
  }
@@ -1,27 +1,17 @@
1
1
  import type { BufferGeometry } from "three";
2
2
  /**
3
- * Utility class for comparing and hashing BufferGeometry instances with tolerance support.
3
+ * Internal utility to identify identical geometries.
4
+ * @internal
4
5
  */
5
6
  export declare class GeometryHasher {
6
7
  /**
7
- * Generates a consistent hash for a BufferGeometry based on its contents and tolerance.
8
+ * Creates a hash for a geometry based on its vertex data.
9
+ * Vertices that differ by less than tolerance are considered the same.
8
10
  *
9
- * @param geometry - The geometry to hash
10
- * @param tolerance - Precision level for number comparison (values within tolerance are considered equal)
11
- * @returns A string hash that will be identical for geometrically equivalent geometries
11
+ * @param geometry - Geometry to hash
12
+ * @param tolerance - How close vertices need to be to count as identical
13
+ * @returns Hash string that's the same for matching geometries
14
+ * @internal
12
15
  */
13
- static getGeometryHash(geometry: BufferGeometry, tolerance?: number): string;
14
- /**
15
- * Compares two BufferGeometry instances for approximate equality.
16
- * Early exit if UUIDs match (same object or cloned geometry).
17
- */
18
- static compare(firstGeometry: BufferGeometry, secondGeometry: BufferGeometry, tolerance?: number): boolean;
19
- /**
20
- * Generates a hash for a buffer attribute with tolerance.
21
- */
22
- private static getAttributeHash;
23
- /**
24
- * Compares two buffer attributes with tolerance.
25
- */
26
- private static compareBufferAttributes;
16
+ static getGeometryHash(geometry: BufferGeometry, tolerance: number): string;
27
17
  }
@@ -1,11 +1,26 @@
1
1
  import type { Object3D } from "three";
2
2
  import { Mesh } from "three";
3
- interface IOptions {
4
- container: Object3D;
5
- filter?: (child: Mesh) => boolean;
6
- geometryTolerance?: number;
3
+ /** Configuration for instance assembly */
4
+ export interface InstanceAssemblerOptions {
5
+ /** Filter which meshes to include */
6
+ filter: (child: Mesh) => boolean;
7
+ /** How close vertices need to be to count as identical */
8
+ geometryTolerance: number;
7
9
  }
10
+ /**
11
+ * Combines identical meshes into instanced versions for better performance.
12
+ * Meshes are considered identical if they share the same geometry and materials.
13
+ */
8
14
  export declare class InstanceAssembler {
9
- static assemble(options: IOptions): void;
15
+ /**
16
+ * Find meshes that can be instanced and combine them.
17
+ * Only processes meshes that:
18
+ * - Have no children
19
+ * - Pass the filter function (if any)
20
+ * - Share geometry with at least one other mesh
21
+ *
22
+ * @param container - Object containing meshes to process
23
+ * @param options - Optional settings
24
+ */
25
+ static assemble(container: Object3D, options?: Partial<InstanceAssemblerOptions>): void;
10
26
  }
11
- export {};
@@ -1,14 +1,29 @@
1
1
  import type { Object3D } from "three";
2
- type IPattern = string | RegExp;
3
- interface IOptions {
4
- asset: Object3D;
5
- castShadowMeshNames?: IPattern[];
6
- receiveShadowMeshNames?: IPattern[];
7
- transparentMaterialNames?: IPattern[];
8
- noDepthWriteMaterialNames?: IPattern[];
2
+ /** Options for scene post-processing */
3
+ export interface SceneProcessorOptions {
4
+ /** Clone the input asset before processing? */
5
+ cloneAsset: boolean;
6
+ /** Combine identical meshes into instances? */
7
+ assembleInstances: boolean;
8
+ /** Names matching these patterns will cast shadows */
9
+ castShadowExpressions: RegExp[];
10
+ /** Names matching these patterns will receive shadows */
11
+ receiveShadwoExpressions: RegExp[];
12
+ /** Names matching these patterns will be transparent */
13
+ transparentMaterialExpressions: RegExp[];
14
+ /** Names matching these patterns won't write to depth buffer */
15
+ noDepthWriteMaterialExpressions: RegExp[];
9
16
  }
17
+ /** Post-processes a scene based on name patterns */
10
18
  export declare class SceneProcessor {
11
- static process(options: IOptions): Object3D[];
19
+ /**
20
+ * Process a scene to set up materials and shadows.
21
+ *
22
+ * @param asset - Scene to process
23
+ * @param options - How to process the scene
24
+ * @returns Processed scene root objects
25
+ */
26
+ static process(asset: Object3D, options: Partial<SceneProcessorOptions>): Object3D[];
27
+ /** Does the string match any of the patterns? */
12
28
  private static matchesAny;
13
29
  }
14
- export {};
@@ -1,12 +1,20 @@
1
1
  import type { Material, Object3D } from "three";
2
- type Constructor<T> = abstract new (...args: never[]) => T;
2
+ /** Constructor type for type-safe scene traversal */
3
+ export type Constructor<T> = abstract new (...args: never[]) => T;
4
+ /** Find and modify objects in a Three.js scene */
3
5
  export declare class SceneTraversal {
6
+ /** Find first object with exact name match */
4
7
  static getObjectByName(object: Object3D, name: string): Object3D | null;
8
+ /** Find first material with exact name match */
5
9
  static getMaterialByName(object: Object3D, name: string): Material | null;
10
+ /** Process all objects of a specific type */
6
11
  static enumerateObjectsByType<T>(object: Object3D, type: Constructor<T>, callback: (instance: T) => void): void;
12
+ /** Process all materials in meshes */
7
13
  static enumerateMaterials(object: Object3D, callback: (material: Material) => void): void;
14
+ /** Find all objects whose names match a pattern */
8
15
  static filterObjects(object: Object3D, name: RegExp): Object3D[];
16
+ /** Find all materials whose names match a pattern */
9
17
  static filterMaterials(object: Object3D, name: RegExp): Material[];
10
- static setShadowRecursive(object: Object3D, castShadow?: boolean, receiveShadow?: boolean): void;
18
+ /** Set shadow properties on meshes */
19
+ static setShadowRecursive(object: Object3D, castShadow?: boolean, receiveShadow?: boolean, filter?: (object: Object3D) => boolean): void;
11
20
  }
12
- export {};
@@ -1,25 +1,23 @@
1
1
  import type { AnimationClip, Object3D, SkinnedMesh } from "three";
2
2
  import { Mesh } from "three";
3
- /**
4
- * Utilities for baking poses and animations from SkinnedMesh into a regular static Mesh.
5
- */
3
+ /** Convert skinned meshes to regular static meshes */
6
4
  export declare class SkinnedMeshBaker {
7
5
  /**
8
- * Bakes the current pose of a SkinnedMesh into a regular geometry.
9
- * Transforms all vertices according to the current skeleton state.
6
+ * Convert a skinned mesh to a regular mesh in its current pose.
7
+ * The resulting mesh will have no bones but look identical.
10
8
  *
11
- * @param skinnedMesh - SkinnedMesh from which to bake the geometry
12
- * @returns A new Mesh with positions corresponding to the current bone positions
9
+ * @param skinnedMesh - Mesh to convert
10
+ * @returns Static mesh with baked vertex positions
13
11
  */
14
12
  static bakePose(skinnedMesh: SkinnedMesh): Mesh;
15
13
  /**
16
- * Bakes a SkinnedMesh in a specific pose derived from an AnimationClip at the given timestamp.
14
+ * Bake a single frame from an animation into a static mesh.
17
15
  *
18
- * @param armature - The parent object (typically an armature from GLTF) containing the bones
19
- * @param skinnedMesh - The SkinnedMesh to be baked
20
- * @param timeOffset - The animation time in seconds to set
21
- * @param clip - The animation clip
22
- * @returns A new Mesh with geometry matching the specified animation frame
16
+ * @param armature - Root object with bones (usually from GLTF)
17
+ * @param skinnedMesh - Mesh to convert
18
+ * @param timeOffset - Time in seconds within the animation
19
+ * @param clip - Animation to get the pose from
20
+ * @returns Static mesh with baked vertex positions
23
21
  */
24
22
  static bakeAnimationFrame(armature: Object3D, skinnedMesh: SkinnedMesh, timeOffset: number, clip: AnimationClip): Mesh;
25
23
  }
package/dist/Sun.d.ts CHANGED
@@ -1,18 +1,8 @@
1
1
  import type { Texture } from "three";
2
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
- */
3
+ /** A directional light with spherical positioning controls */
15
4
  export declare class Sun extends DirectionalLight {
5
+ /** Internal vectors to avoid garbage collection */
16
6
  private readonly tempVector3D0;
17
7
  private readonly tempVector3D1;
18
8
  private readonly tempVector3D2;
@@ -23,49 +13,20 @@ export declare class Sun extends DirectionalLight {
23
13
  private readonly tempVector3D7;
24
14
  private readonly tempBox3;
25
15
  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
- */
16
+ /** Distance from the light to its target */
30
17
  get distance(): number;
31
- /**
32
- * Gets the elevation angle of the sun (phi in spherical coordinates)
33
- * @returns The elevation in radians
34
- */
18
+ /** Vertical angle from the ground in radians */
35
19
  get elevation(): number;
36
- /**
37
- * Gets the azimuth angle of the sun (theta in spherical coordinates)
38
- * @returns The azimuth in radians
39
- */
20
+ /** Horizontal angle around the target in radians */
40
21
  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
- */
22
+ /** Set distance while keeping current angles */
45
23
  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
- */
24
+ /** Set elevation while keeping current distance and azimuth */
50
25
  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
- */
26
+ /** Set azimuth while keeping current distance and elevation */
55
27
  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
- */
28
+ /** Configure shadows to cover all corners of a bounding box */
62
29
  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
- */
30
+ /** Set light direction based on brightest point in an HDR texture */
70
31
  setDirectionFromHDR(texture: Texture, distance?: number): void;
71
32
  }