@gadxr/aframe-bvh 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 arsra
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,34 @@
1
- # Temporary Holding Version
1
+ # @gadxr/aframe-bvh
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Fast raycasts against big static meshes in A-Frame, with
4
+ [three-mesh-bvh](https://github.com/gkjohnson/three-mesh-bvh). A bounding volume hierarchy lets a
5
+ ray test a handful of triangles instead of every one, which matters for teleport: `blink-controls`
6
+ casts 10–20 short rays per frame while you aim, and without a tree each tests every triangle of
7
+ every collision mesh it comes near.
8
+
9
+ ```js
10
+ import 'aframe'; // first: this package patches A-Frame's three.js
11
+ import '@gadxr/aframe-bvh';
12
+ ```
13
+
14
+ ```html
15
+ <a-entity gltf-model="#scan" class="floor" bvh></a-entity>
16
+ ```
17
+
18
+ - Importing it patches `THREE.Mesh.prototype.raycast` for the whole page. Meshes without a tree
19
+ raycast exactly as before, so the UI lasers and everything else are unaffected.
20
+ - `bvh` builds a tree for every mesh under its entity, including child entities and meshes set
21
+ later (a model that finishes loading). Building costs time once per mesh: about 4 ms for 2k triangles, 130 ms for 500k triangles, measured on an M-series Mac.
22
+ - Only for meshes whose vertices don't change afterwards: the tree isn't rebuilt. (A geometry
23
+ that's replaced raycasts the old way until something sets a mesh on the entity again.)
24
+
25
+ ## One three.js
26
+
27
+ three-mesh-bvh imports `'three'` and has to get the copy A-Frame renders with. With A-Frame from
28
+ npm that's `super-three`, which this package depends on as `three` at A-Frame 1.8's version, so
29
+ pnpm gives three-mesh-bvh the same package: no config needed. Keep that version A-Frame's when
30
+ upgrading A-Frame; otherwise the page gets a second three.js and this warns
31
+ `three-mesh-bvh got a different three.js than A-Frame's`.
32
+
33
+ A page that loads A-Frame with a script tag aliases `'three'` in its Vite config
34
+ to a module that re-exports the global `THREE` (`src/three-global.js`).
package/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ // Patches A-Frame's three.js and registers the `bvh` component on the global AFRAME; exports nothing.
2
+ export {};
package/package.json CHANGED
@@ -1,6 +1,35 @@
1
1
  {
2
2
  "name": "@gadxr/aframe-bvh",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "Fast raycasts against big static meshes (teleport, navmesh walking) in A-Frame, with three-mesh-bvh.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/gad-sh/xr-kit.git",
8
+ "directory": "packages/aframe-bvh"
9
+ },
10
+ "license": "MIT",
11
+ "type": "module",
12
+ "main": "src/index.js",
13
+ "types": "index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./index.d.ts",
17
+ "default": "./src/index.js"
18
+ }
19
+ },
20
+ "sideEffects": true,
21
+ "files": [
22
+ "src",
23
+ "index.d.ts"
24
+ ],
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "dependencies": {
29
+ "three": "npm:super-three@0.184.0",
30
+ "three-mesh-bvh": "^0.9.16"
31
+ },
32
+ "peerDependencies": {
33
+ "aframe": "^1.8.0"
34
+ }
6
35
  }
package/src/index.js ADDED
@@ -0,0 +1,36 @@
1
+ // Fast raycasts against big static meshes with three-mesh-bvh: a bounding volume hierarchy lets a
2
+ // ray test a few triangles instead of all of them (teleport arcs cast many short rays every frame).
3
+ // Importing this patches A-Frame's three.js once, for every raycast in the page; meshes without
4
+ // a tree raycast exactly as before. Put `bvh` on an entity to build trees for its meshes.
5
+ import { Mesh } from 'three';
6
+ import { acceleratedRaycast, computeBoundsTree, disposeBoundsTree } from 'three-mesh-bvh';
7
+
8
+ // three-mesh-bvh has to extend the three.js A-Frame renders with. With npm A-Frame that's
9
+ // super-three, which this package depends on as 'three' (keep its version A-Frame's); a page
10
+ // that loads A-Frame with a script tag aliases 'three' to the global instead.
11
+ const { THREE } = AFRAME;
12
+ if (Mesh !== THREE.Mesh) console.warn("aframe-bvh: three-mesh-bvh got a different three.js than A-Frame's");
13
+ THREE.BufferGeometry.prototype.computeBoundsTree = computeBoundsTree;
14
+ THREE.BufferGeometry.prototype.disposeBoundsTree = disposeBoundsTree;
15
+ THREE.Mesh.prototype.raycast = acceleratedRaycast;
16
+
17
+ // Builds a tree for every mesh under the entity, now and whenever one is set (`object3dset`
18
+ // bubbles up from child entities). Only for meshes whose vertices don't move afterwards:
19
+ // the tree isn't rebuilt when they change (a replaced geometry just raycasts the old way).
20
+ AFRAME.registerComponent('bvh', {
21
+ // No options: a single property, so a bare `bvh` attribute parses without a warning.
22
+ schema: { type: 'boolean', default: true },
23
+ init() {
24
+ this.build = this.build.bind(this);
25
+ this.el.addEventListener('object3dset', this.build);
26
+ this.build();
27
+ },
28
+ remove() {
29
+ this.el.removeEventListener('object3dset', this.build);
30
+ },
31
+ build() {
32
+ this.el.object3D.traverse((o) => {
33
+ if (o.isMesh && !o.geometry.boundsTree && o.geometry.attributes.position) o.geometry.computeBoundsTree();
34
+ });
35
+ },
36
+ });