three-tunnel is a tunnel & grouting library for three.js powering the Tunnel Sketcher demo application. It helps visualize underground tunnel geometry, grouting patterns, and geological fracture planes with a focus on clarity and interactivity. Use the components directly to build your own tunnel design or geological visualization tools.
Tunnel3D) with adjustable length, width, height and roof curvature.Grout3D instances via TunnelControls).FracturePlane3D) with strike, dip, positional offsets, opacity and color.three-mesh-bvh acceleration.npm install three-tunnel
# or
yarn add three-tunnel
Peer dependency: three (install a compatible version if not already present).
import * as THREE from 'three';
import { Tunnel3D, TunnelControls } from 'three-tunnel';
const scene = new THREE.Scene();
// 1. Create a tunnel
const tunnel = new Tunnel3D();
scene.add(tunnel);
// 2. Attach interactive controls (optionally pass a group/root object)
const controls = new TunnelControls(scene);
controls.attach(tunnel);
// 3. Add two initial grouts and update derived geometry
const grout1 = controls.addGrout();
const grout2 = controls.addGrout();
controls.update();
// 4. Change parameters (angles given in radians)
controls.setGroutParams(0, { angle: 15 * THREE.MathUtils.DEG2RAD, holeLength: 25 });
controls.setTunnelParams({ tunnelLength: 60, tunnelWidth: 12 });
controls.update();
Represents an extruded tunnel profile. Adjustable fields include: tunnelLength, tunnelWidth, tunnelHeight, tunnelRoofHeight, tunnelColorHEX. Use TunnelControls.setTunnelParams() to modify and propagate changes.
Represents a screen (array) of grout holes. Key parameters: angle (radians from horizontal), holeLength, overlap, screenLength, groutColorHEX, isVisible. Add via TunnelControls.addGrout() then mutate with setGroutParams(index, params).
Visual geological plane with adjustable strike, dip, xPosition, yPosition, zPosition, planeColorHEX, opacity, visible. Use plane.update() after modifying direct properties (or use provided param helpers if exposed).
Central coordinator for updating tunnel and grout geometry. Typical flow:
const controls = new TunnelControls(groupOrScene);controls.attach(tunnel);controls.addGrout();controls.setTunnelParams({...}) / controls.setGroutParams(i, {...});controls.update(); to rebuild geometry.If you mirror the example viewer pattern, you can serialize a full session via toJSON() and restore with fromJSON(json). See example/Viewer.ts for the schema referenced by the JSONParams type.
Real-time edge intersection line segments are generated between the tunnel surface and each visible fracture plane using three-mesh-bvh's bvhcast triangle-pair traversal.
Implementation highlights:
THREE.LineSegments object storing intersection edges for that frame.Code location: _updatePlaneTunnelIntersections() inside example/Viewer.ts.
You can explore a full UI in the bundled demo.
Run locally:
git clone https://github.com/andrewisen-tikab/three-tunnel.git
cd three-tunnel
yarn install # or npm install
yarn dev # launches Vite dev server for the example
Open the printed local URL (usually http://localhost:5173/) to interact.
Build the example static site:
yarn build:example
Output goes to dist/examples (served on GitHub Pages at /example/).
Production library build:
yarn build
Outputs compiled module bundle + types to dist/.
Live demo: https://andrewisen-tikab.github.io/three-tunnel/example/
Auto-generated TypeDoc: https://andrewisen-tikab.github.io/three-tunnel/docs/
Regenerate locally:
yarn docs
Outputs HTML docs to the configured docs directory (see typedoc.json).
Contributions are welcome! Suggested workflow:
dev (or next if testing upcoming changes):git checkout dev
git checkout -b feat/your-feature-name
yarn install).yarn dev) and implement changes in src/.yarn lint
yarn build
yarn docs
dev describing the change, screenshots/GIFs encouraged.Testing: (Lightweight) The project currently relies on manual visual verification. If you add logic-heavy features, consider adding unit tests (e.g. with Vitest) and update this section.
Versioning: The version script (yarn version) runs setVersion.cjs to keep internal VERSION references aligned.
Feel free to open an issue to discuss any of these or propose new ones.
| Issue | Possible Fix |
|---|---|
Peer dependency warning for three |
Install a compatible version: yarn add three@^0.157.0 |
| Intersections not appearing | Ensure planes are visible and tunnel length/width > 0; check console for BVH errors. |
| Grout updates not reflected | Make sure to call tunnelControls.update() after changing parameters. |
| Clipping hides wrong side | Confirm you are on the latest branch; logic in _updateTunnelClipping() was recently adjusted. |
MIT © André Wisén and contributors.
Early-stage / work in progress. Expect breaking changes until a 1.0 release.