@flighthq/spatial 0.3.1-next.975.01aea94 → 0.4.0-edge.1908.751021c

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.
Files changed (57) hide show
  1. package/dist/bvh3D.d.ts +3 -0
  2. package/dist/bvh3D.d.ts.map +1 -0
  3. package/dist/bvh3D.js +575 -0
  4. package/dist/bvh3D.js.map +1 -0
  5. package/dist/contract.d.ts +6 -1
  6. package/dist/contract.d.ts.map +1 -1
  7. package/dist/contract.js +6 -1
  8. package/dist/contract.js.map +1 -1
  9. package/dist/explainSpatialIndexing2D.d.ts +3 -0
  10. package/dist/explainSpatialIndexing2D.d.ts.map +1 -0
  11. package/dist/{explainSpatialIndexing.js → explainSpatialIndexing2D.js} +2 -2
  12. package/dist/explainSpatialIndexing2D.js.map +1 -0
  13. package/dist/explainSpatialIndexing3D.d.ts +3 -0
  14. package/dist/explainSpatialIndexing3D.d.ts.map +1 -0
  15. package/dist/explainSpatialIndexing3D.js +15 -0
  16. package/dist/explainSpatialIndexing3D.js.map +1 -0
  17. package/dist/formatSpatialIndexingNotice.d.ts.map +1 -1
  18. package/dist/formatSpatialIndexingNotice.js +8 -2
  19. package/dist/formatSpatialIndexingNotice.js.map +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +1 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/spatialIndex.d.ts +10 -10
  25. package/dist/spatialIndex.d.ts.map +1 -1
  26. package/dist/spatialIndex.js +14 -14
  27. package/dist/spatialIndex.js.map +1 -1
  28. package/dist/spatialIndex3D.d.ts +13 -0
  29. package/dist/spatialIndex3D.d.ts.map +1 -0
  30. package/dist/spatialIndex3D.js +166 -0
  31. package/dist/spatialIndex3D.js.map +1 -0
  32. package/dist/spatialIndexingGuard.d.ts +4 -0
  33. package/dist/spatialIndexingGuard.d.ts.map +1 -0
  34. package/dist/spatialIndexingGuard.js +23 -0
  35. package/dist/spatialIndexingGuard.js.map +1 -0
  36. package/dist/uniformGrid.d.ts +2 -3
  37. package/dist/uniformGrid.d.ts.map +1 -1
  38. package/dist/uniformGrid.js +5 -15
  39. package/dist/uniformGrid.js.map +1 -1
  40. package/dist/uniformGrid3D.d.ts +3 -0
  41. package/dist/uniformGrid3D.d.ts.map +1 -0
  42. package/dist/uniformGrid3D.js +627 -0
  43. package/dist/uniformGrid3D.js.map +1 -0
  44. package/package.json +3 -3
  45. package/src/bvh3D.test.ts +294 -0
  46. package/src/explainSpatialIndexing2D.test.ts +81 -0
  47. package/src/explainSpatialIndexing3D.test.ts +59 -0
  48. package/src/formatSpatialIndexingNotice.test.ts +30 -4
  49. package/src/spatialIndex.test.ts +65 -65
  50. package/src/spatialIndex3D.test.ts +273 -0
  51. package/src/spatialIndexingGuard.test.ts +188 -0
  52. package/src/uniformGrid.test.ts +54 -182
  53. package/src/uniformGrid3D.test.ts +358 -0
  54. package/dist/explainSpatialIndexing.d.ts +0 -3
  55. package/dist/explainSpatialIndexing.d.ts.map +0 -1
  56. package/dist/explainSpatialIndexing.js.map +0 -1
  57. package/src/explainSpatialIndexing.test.ts +0 -76
@@ -0,0 +1,3 @@
1
+ import type { SpatialIndex2D, SpatialIndexingExplanation, SpatialObjectId } from '@flighthq/types/contract';
2
+ export declare function explainSpatialIndexing2D(index: Readonly<SpatialIndex2D>, id: SpatialObjectId): SpatialIndexingExplanation;
3
+ //# sourceMappingURL=explainSpatialIndexing2D.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explainSpatialIndexing2D.d.ts","sourceRoot":"","sources":["../src/explainSpatialIndexing2D.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAY5G,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,EAAE,EAAE,eAAe,GAClB,0BAA0B,CAE5B"}
@@ -8,7 +8,7 @@
8
8
  // This is the pull half of the diagnostics convention, and the measurement seam a regression test
9
9
  // asserts the cost bound against: `bucketCount` is the number that goes unbounded when the bound is
10
10
  // removed, so a test can pin it without timing anything.
11
- export function explainSpatialIndexing(index, id) {
11
+ export function explainSpatialIndexing2D(index, id) {
12
12
  return index.runtime.backend.explainSpatialIndexing(id);
13
13
  }
14
- //# sourceMappingURL=explainSpatialIndexing.js.map
14
+ //# sourceMappingURL=explainSpatialIndexing2D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explainSpatialIndexing2D.js","sourceRoot":"","sources":["../src/explainSpatialIndexing2D.ts"],"names":[],"mappings":"AAEA,qGAAqG;AACrG,sGAAsG;AACtG,+FAA+F;AAC/F,sGAAsG;AACtG,6FAA6F;AAC7F,yBAAyB;AACzB,EAAE;AACF,kGAAkG;AAClG,oGAAoG;AACpG,yDAAyD;AACzD,MAAM,UAAU,wBAAwB,CACtC,KAA+B,EAC/B,EAAmB;IAEnB,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SpatialIndex3D, SpatialIndexingExplanation, SpatialObjectId } from '@flighthq/types/contract';
2
+ export declare function explainSpatialIndexing3D(index: Readonly<SpatialIndex3D>, id: SpatialObjectId): SpatialIndexingExplanation;
3
+ //# sourceMappingURL=explainSpatialIndexing3D.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explainSpatialIndexing3D.d.ts","sourceRoot":"","sources":["../src/explainSpatialIndexing3D.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAa5G,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,EAAE,EAAE,eAAe,GAClB,0BAA0B,CAE5B"}
@@ -0,0 +1,15 @@
1
+ // Reports how the index is currently holding `id`, as plain data. Pure: reads only, indexes nothing,
2
+ // never throws on an unknown id, and retains no reference to the backend. Import it to answer "why is
3
+ // this object not in my query results?" — `absent` means it was never inserted or was removed,
4
+ // `declined` means its bounds were non-finite or inverted and it is deliberately not held, `overflow`
5
+ // means it is held but cannot be usefully bucketed, and `cells` reports the bucket count the
6
+ // per-object bound caps.
7
+ //
8
+ // This is the pull half of the diagnostics convention, and the measurement seam a regression test
9
+ // asserts the cost bound against: `bucketCount` is the number that goes unbounded when the bound is
10
+ // removed, so a test can pin it without timing anything. It matters more here than in 2D — the span
11
+ // a missing bound would walk grows with the cube of an object's extent rather than the square.
12
+ export function explainSpatialIndexing3D(index, id) {
13
+ return index.runtime.backend.explainSpatialIndexing(id);
14
+ }
15
+ //# sourceMappingURL=explainSpatialIndexing3D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explainSpatialIndexing3D.js","sourceRoot":"","sources":["../src/explainSpatialIndexing3D.ts"],"names":[],"mappings":"AAEA,qGAAqG;AACrG,sGAAsG;AACtG,+FAA+F;AAC/F,sGAAsG;AACtG,6FAA6F;AAC7F,yBAAyB;AACzB,EAAE;AACF,kGAAkG;AAClG,oGAAoG;AACpG,oGAAoG;AACpG,+FAA+F;AAC/F,MAAM,UAAU,wBAAwB,CACtC,KAA+B,EAC/B,EAAmB;IAEnB,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"formatSpatialIndexingNotice.d.ts","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAiBtE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,MAAM,CAsB3F"}
1
+ {"version":3,"file":"formatSpatialIndexingNotice.d.ts","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAuBtE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,MAAM,CAsB3F"}
@@ -3,6 +3,12 @@ import { MAX_INDEXED_CELLS_PER_OBJECT } from './uniformGrid';
3
3
  // holds one. Import it to turn the structured record a SpatialIndexingGuard receives into something a
4
4
  // developer reads; leave it unimported and neither the text nor its cost reaches a bundle.
5
5
  //
6
+ // The sentences name the UNSUFFIXED backend methods (`removeSpatialObject`), never the dimensioned
7
+ // free-function wrappers. A notice carries no axis — one guard serves both dimensions — so there is
8
+ // nothing here from which to pick 2D or 3D, and naming one would misdescribe every notice from the
9
+ // other. The unsuffixed names are also the ones a caller greps: they are what the backend seam
10
+ // declares and what a consumer like physics3d actually calls.
11
+ //
6
12
  // This package deliberately stops at the structured guard seam plus this optional formatter rather
7
13
  // than adding an `enableSpatialGuards` that chooses reporting policy. A caller can send the record to
8
14
  // tests, telemetry, a host sink, or `@flighthq/log`, choosing its own channel and deduplication. An
@@ -14,10 +20,10 @@ import { MAX_INDEXED_CELLS_PER_OBJECT } from './uniformGrid';
14
20
  // setSpatialIndexingGuard((notice) => logWarn({ message: formatSpatialIndexingNotice(notice) }, 'spatial'));
15
21
  export function formatSpatialIndexingNotice(notice) {
16
22
  if (notice.reason === 'invalid-cell-size') {
17
- return `createUniformGridSpatialBackend(${notice.cellSize}): cellSize must be a positive finite number. ${notice.operation}SpatialObject(${notice.id}) used the bounded overflow path instead, so results remain correct but queries scan this object.`;
23
+ return `the uniform grid's cellSize (${notice.cellSize}) must be a positive finite number. ${notice.operation}SpatialObject(${notice.id}) used the bounded overflow path instead, so results remain correct but queries scan this object.`;
18
24
  }
19
25
  if (notice.reason === 'inverted-bounds') {
20
- return `${notice.operation}SpatialObject(${notice.id}): minX/minY must not exceed maxX/maxY, so the object was not indexed and no query will return it. The operation returns false for this — normalize or correct the bounds upstream.`;
26
+ return `${notice.operation}SpatialObject(${notice.id}): no minimum may exceed its matching maximum, so the object was not indexed and no query will return it. The operation returns false for this — normalize or correct the bounds upstream.`;
21
27
  }
22
28
  if (notice.reason === 'missing-id') {
23
29
  if (notice.operation === 'remove') {
@@ -1 +1 @@
1
- {"version":3,"file":"formatSpatialIndexingNotice.js","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAE7D,qGAAqG;AACrG,sGAAsG;AACtG,2FAA2F;AAC3F,EAAE;AACF,mGAAmG;AACnG,sGAAsG;AACtG,oGAAoG;AACpG,sGAAsG;AACtG,wGAAwG;AACxG,wGAAwG;AACxG,2CAA2C;AAC3C,EAAE;AACF,+GAA+G;AAC/G,MAAM,UAAU,2BAA2B,CAAC,MAAuC;IACjF,IAAI,MAAM,CAAC,MAAM,KAAK,mBAAmB,EAAE,CAAC;QAC1C,OAAO,mCAAmC,MAAM,CAAC,QAAQ,iDAAiD,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,mGAAmG,CAAC;IAC1P,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;QACxC,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,qLAAqL,CAAC;IAC5O,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QACnC,IAAI,MAAM,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,uBAAuB,MAAM,CAAC,EAAE,kHAAkH,CAAC;QAC5J,CAAC;QACD,OAAO,uBAAuB,MAAM,CAAC,EAAE,oGAAoG,MAAM,CAAC,IAAI,yFAAyF,CAAC;IAClP,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,2MAA2M,CAAC;IAClQ,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,sBAAsB,MAAM,CAAC,sBAAsB,oBAAoB,4BAA4B,kPAAkP,CAAC;IAC5Y,CAAC;IACD,gGAAgG;IAChG,oGAAoG;IACpG,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,kBAAkB,MAAM,CAAC,IAAI,2CAA2C,CAAC;AAC/H,CAAC"}
1
+ {"version":3,"file":"formatSpatialIndexingNotice.js","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAE7D,qGAAqG;AACrG,sGAAsG;AACtG,2FAA2F;AAC3F,EAAE;AACF,mGAAmG;AACnG,oGAAoG;AACpG,mGAAmG;AACnG,+FAA+F;AAC/F,8DAA8D;AAC9D,EAAE;AACF,mGAAmG;AACnG,sGAAsG;AACtG,oGAAoG;AACpG,sGAAsG;AACtG,wGAAwG;AACxG,wGAAwG;AACxG,2CAA2C;AAC3C,EAAE;AACF,+GAA+G;AAC/G,MAAM,UAAU,2BAA2B,CAAC,MAAuC;IACjF,IAAI,MAAM,CAAC,MAAM,KAAK,mBAAmB,EAAE,CAAC;QAC1C,OAAO,gCAAgC,MAAM,CAAC,QAAQ,uCAAuC,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,mGAAmG,CAAC;IAC7O,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;QACxC,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,4LAA4L,CAAC;IACnP,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QACnC,IAAI,MAAM,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,uBAAuB,MAAM,CAAC,EAAE,kHAAkH,CAAC;QAC5J,CAAC;QACD,OAAO,uBAAuB,MAAM,CAAC,EAAE,oGAAoG,MAAM,CAAC,IAAI,yFAAyF,CAAC;IAClP,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,2MAA2M,CAAC;IAClQ,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,sBAAsB,MAAM,CAAC,sBAAsB,oBAAoB,4BAA4B,kPAAkP,CAAC;IAC5Y,CAAC;IACD,gGAAgG;IAChG,oGAAoG;IACpG,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,kBAAkB,MAAM,CAAC,IAAI,2CAA2C,CAAC;AAC/H,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { MAX_INDEXED_CELLS_PER_OBJECT, clearSpatialIndex, createSpatialIndex, createUniformGridSpatialBackend, explainSpatialIndexing, formatSpatialIndexingNotice, insertSpatialObject, querySpatialPairs, querySpatialPoint, querySpatialRay, querySpatialRegion, removeSpatialObject, setSpatialIndexingGuard, updateSpatialObject, } from './contract';
1
+ export { MAX_INDEXED_CELLS_PER_OBJECT, clearSpatialIndex2D, clearSpatialIndex3D, createSpatialIndex2D, createSpatialIndex3D, createUniformGridSpatialBackend2D, createBvhSpatialBackend3D, createUniformGridSpatialBackend3D, explainSpatialIndexing2D, explainSpatialIndexing3D, formatSpatialIndexingNotice, insertSpatialObject2D, insertSpatialObject3D, querySpatialPairs2D, querySpatialPairs3D, querySpatialPoint2D, querySpatialPoint3D, querySpatialRay2D, querySpatialRay3D, querySpatialRegion2D, querySpatialFrustum3D, querySpatialRegion3D, querySpatialSphere3D, removeSpatialObject2D, removeSpatialObject3D, setSpatialIndexingGuard, updateSpatialObject2D, updateSpatialObject3D, } from './contract';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,iBAAiB,EACjB,kBAAkB,EAClB,+BAA+B,EAC/B,sBAAsB,EACtB,2BAA2B,EAC3B,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,iCAAiC,EACjC,yBAAyB,EACzB,iCAAiC,EACjC,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC3B,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { MAX_INDEXED_CELLS_PER_OBJECT, clearSpatialIndex, createSpatialIndex, createUniformGridSpatialBackend, explainSpatialIndexing, formatSpatialIndexingNotice, insertSpatialObject, querySpatialPairs, querySpatialPoint, querySpatialRay, querySpatialRegion, removeSpatialObject, setSpatialIndexingGuard, updateSpatialObject, } from './contract';
1
+ export { MAX_INDEXED_CELLS_PER_OBJECT, clearSpatialIndex2D, clearSpatialIndex3D, createSpatialIndex2D, createSpatialIndex3D, createUniformGridSpatialBackend2D, createBvhSpatialBackend3D, createUniformGridSpatialBackend3D, explainSpatialIndexing2D, explainSpatialIndexing3D, formatSpatialIndexingNotice, insertSpatialObject2D, insertSpatialObject3D, querySpatialPairs2D, querySpatialPairs3D, querySpatialPoint2D, querySpatialPoint3D, querySpatialRay2D, querySpatialRay3D, querySpatialRegion2D, querySpatialFrustum3D, querySpatialRegion3D, querySpatialSphere3D, removeSpatialObject2D, removeSpatialObject3D, setSpatialIndexingGuard, updateSpatialObject2D, updateSpatialObject3D, } from './contract';
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,iBAAiB,EACjB,kBAAkB,EAClB,+BAA+B,EAC/B,sBAAsB,EACtB,2BAA2B,EAC3B,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,iCAAiC,EACjC,yBAAyB,EACzB,iCAAiC,EACjC,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC3B,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
@@ -1,11 +1,11 @@
1
- import type { SpatialAabb, SpatialIndex, SpatialIndexBackend, SpatialObjectId, SpatialPair } from '@flighthq/types/contract';
2
- export declare function clearSpatialIndex(index: Readonly<SpatialIndex>): void;
3
- export declare function createSpatialIndex(backend?: SpatialIndexBackend): SpatialIndex;
4
- export declare function insertSpatialObject(index: Readonly<SpatialIndex>, id: SpatialObjectId, bounds: Readonly<SpatialAabb>): boolean;
5
- export declare function querySpatialPairs(index: Readonly<SpatialIndex>, out: SpatialPair[]): void;
6
- export declare function querySpatialPoint(index: Readonly<SpatialIndex>, x: number, y: number, out: SpatialObjectId[]): void;
7
- export declare function querySpatialRay(index: Readonly<SpatialIndex>, x: number, y: number, dx: number, dy: number, out: SpatialObjectId[]): void;
8
- export declare function querySpatialRegion(index: Readonly<SpatialIndex>, region: Readonly<SpatialAabb>, out: SpatialObjectId[]): void;
9
- export declare function removeSpatialObject(index: Readonly<SpatialIndex>, id: SpatialObjectId): void;
10
- export declare function updateSpatialObject(index: Readonly<SpatialIndex>, id: SpatialObjectId, bounds: Readonly<SpatialAabb>): boolean;
1
+ import type { SpatialAabb2D, SpatialIndex2D, SpatialIndexBackend2D, SpatialObjectId, SpatialPair } from '@flighthq/types/contract';
2
+ export declare function clearSpatialIndex2D(index: Readonly<SpatialIndex2D>): void;
3
+ export declare function createSpatialIndex2D(backend?: SpatialIndexBackend2D): SpatialIndex2D;
4
+ export declare function insertSpatialObject2D(index: Readonly<SpatialIndex2D>, id: SpatialObjectId, bounds: Readonly<SpatialAabb2D>): boolean;
5
+ export declare function querySpatialPairs2D(index: Readonly<SpatialIndex2D>, out: SpatialPair[]): void;
6
+ export declare function querySpatialPoint2D(index: Readonly<SpatialIndex2D>, x: number, y: number, out: SpatialObjectId[]): void;
7
+ export declare function querySpatialRay2D(index: Readonly<SpatialIndex2D>, x: number, y: number, dx: number, dy: number, out: SpatialObjectId[]): void;
8
+ export declare function querySpatialRegion2D(index: Readonly<SpatialIndex2D>, region: Readonly<SpatialAabb2D>, out: SpatialObjectId[]): void;
9
+ export declare function removeSpatialObject2D(index: Readonly<SpatialIndex2D>, id: SpatialObjectId): void;
10
+ export declare function updateSpatialObject2D(index: Readonly<SpatialIndex2D>, id: SpatialObjectId, bounds: Readonly<SpatialAabb2D>): boolean;
11
11
  //# sourceMappingURL=spatialIndex.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spatialIndex.d.ts","sourceRoot":"","sources":["../src/spatialIndex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAKlC,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,IAAI,CAErE;AAMD,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,YAAY,CAM9E;AAOD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC7B,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,OAAO,CAET;AAKD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,IAAI,CAEzF;AAGD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,IAAI,CAEnH;AAID,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC7B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,eAAe,EAAE,GACrB,IAAI,CAEN;AAGD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC7B,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC7B,GAAG,EAAE,eAAe,EAAE,GACrB,IAAI,CAEN;AAGD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,eAAe,GAAG,IAAI,CAE5F;AAMD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC7B,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,OAAO,CAET"}
1
+ {"version":3,"file":"spatialIndex.d.ts","sourceRoot":"","sources":["../src/spatialIndex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAKlC,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,IAAI,CAEzE;AAMD,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,cAAc,CAMpF;AAOD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,GAC9B,OAAO,CAET;AAKD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,IAAI,CAE7F;AAGD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,GAAG,EAAE,eAAe,EAAE,GACrB,IAAI,CAEN;AAID,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,eAAe,EAAE,GACrB,IAAI,CAEN;AAGD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC/B,GAAG,EAAE,eAAe,EAAE,GACrB,IAAI,CAEN;AAGD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,eAAe,GAAG,IAAI,CAEhG;AAMD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,GAC9B,OAAO,CAET"}
@@ -1,16 +1,16 @@
1
- import { createUniformGridSpatialBackend } from './uniformGrid';
1
+ import { createUniformGridSpatialBackend2D } from './uniformGrid';
2
2
  // Empties the index of all objects while keeping it (and its backend) reusable.
3
- export function clearSpatialIndex(index) {
3
+ export function clearSpatialIndex2D(index) {
4
4
  index.runtime.backend.clearSpatialIndex();
5
5
  }
6
6
  // Creates a 2D broadphase index. With no backend it defaults to a uniform grid sized for
7
7
  // medium-scale scenes; pass an explicit backend (a differently-sized grid, or a future quadtree /
8
8
  // sweep-and-prune) to select the structure for the workload. Constructing the default grid happens
9
9
  // here, on call — importing the package has no side effect.
10
- export function createSpatialIndex(backend) {
10
+ export function createSpatialIndex2D(backend) {
11
11
  return {
12
12
  runtime: {
13
- backend: backend ?? createUniformGridSpatialBackend(DEFAULT_SPATIAL_CELL_SIZE),
13
+ backend: backend ?? createUniformGridSpatialBackend2D(DEFAULT_SPATIAL_CELL_SIZE),
14
14
  },
15
15
  };
16
16
  }
@@ -18,41 +18,41 @@ export function createSpatialIndex(backend) {
18
18
  // may reuse its own value afterward. Returns false when the bounds cannot be indexed at all
19
19
  // (non-finite or inverted) — the object is then absent from every query rather than present at a
20
20
  // nonsense position. Oversized-but-valid bounds return true and stay fully queryable; the backend
21
- // decides how to hold them. explainSpatialIndexing reports which happened.
22
- export function insertSpatialObject(index, id, bounds) {
21
+ // decides how to hold them. explainSpatialIndexing2D reports which happened.
22
+ export function insertSpatialObject2D(index, id, bounds) {
23
23
  return index.runtime.backend.insertSpatialObject(id, bounds);
24
24
  }
25
25
  // Fills `out` (cleared first) with every deduplicated candidate pair — each unordered pair at most
26
26
  // once, never an object with itself. A pair is a broadphase candidate: the two objects are close
27
27
  // enough to be worth a narrow-phase test, which the caller (or @flighthq/collision) performs.
28
- export function querySpatialPairs(index, out) {
28
+ export function querySpatialPairs2D(index, out) {
29
29
  index.runtime.backend.querySpatialPairs(out);
30
30
  }
31
31
  // Fills `out` (cleared first) with the ids whose bounds contain the point (`x`,`y`).
32
- export function querySpatialPoint(index, x, y, out) {
32
+ export function querySpatialPoint2D(index, x, y, out) {
33
33
  index.runtime.backend.querySpatialPoint(x, y, out);
34
34
  }
35
35
  // Fills `out` (cleared first) with the ids whose bounds the ray from (`x`,`y`) along (`dx`,`dy`)
36
36
  // intersects. The direction need not be normalized; the ray is treated as extending forward only.
37
- export function querySpatialRay(index, x, y, dx, dy, out) {
37
+ export function querySpatialRay2D(index, x, y, dx, dy, out) {
38
38
  index.runtime.backend.querySpatialRay(x, y, dx, dy, out);
39
39
  }
40
40
  // Fills `out` (cleared first) with the ids whose bounds overlap `region`.
41
- export function querySpatialRegion(index, region, out) {
41
+ export function querySpatialRegion2D(index, region, out) {
42
42
  index.runtime.backend.querySpatialRegion(region, out);
43
43
  }
44
44
  // Removes an object from the index. A no-op if the id is not present.
45
- export function removeSpatialObject(index, id) {
45
+ export function removeSpatialObject2D(index, id) {
46
46
  index.runtime.backend.removeSpatialObject(id);
47
47
  }
48
48
  // Moves an already-inserted object to new bounds. Inserting a not-yet-present id behaves as insert.
49
- // Returns the same sentinel as insertSpatialObject. A declined update removes the object rather than
49
+ // Returns the same sentinel as insertSpatialObject2D. A declined update removes the object rather than
50
50
  // leaving it at its old bounds, so a caller that ignores the sentinel can never read a stale position
51
51
  // as a current one.
52
- export function updateSpatialObject(index, id, bounds) {
52
+ export function updateSpatialObject2D(index, id, bounds) {
53
53
  return index.runtime.backend.updateSpatialObject(id, bounds);
54
54
  }
55
- // The default uniform-grid cell size when createSpatialIndex is called without an explicit backend —
55
+ // The default uniform-grid cell size when createSpatialIndex2D is called without an explicit backend —
56
56
  // a middle-of-the-road choice; a workload with a known typical object size should pass its own grid.
57
57
  const DEFAULT_SPATIAL_CELL_SIZE = 128;
58
58
  //# sourceMappingURL=spatialIndex.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spatialIndex.js","sourceRoot":"","sources":["../src/spatialIndex.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAEhE,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;AAC5C,CAAC;AAED,yFAAyF;AACzF,kGAAkG;AAClG,mGAAmG;AACnG,4DAA4D;AAC5D,MAAM,UAAU,kBAAkB,CAAC,OAA6B;IAC9D,OAAO;QACL,OAAO,EAAE;YACP,OAAO,EAAE,OAAO,IAAI,+BAA+B,CAAC,yBAAyB,CAAC;SAC/E;KACF,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,4FAA4F;AAC5F,iGAAiG;AACjG,kGAAkG;AAClG,2EAA2E;AAC3E,MAAM,UAAU,mBAAmB,CACjC,KAA6B,EAC7B,EAAmB,EACnB,MAA6B;IAE7B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,mGAAmG;AACnG,iGAAiG;AACjG,8FAA8F;AAC9F,MAAM,UAAU,iBAAiB,CAAC,KAA6B,EAAE,GAAkB;IACjF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAC/C,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,iBAAiB,CAAC,KAA6B,EAAE,CAAS,EAAE,CAAS,EAAE,GAAsB;IAC3G,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;AACrD,CAAC;AAED,iGAAiG;AACjG,kGAAkG;AAClG,MAAM,UAAU,eAAe,CAC7B,KAA6B,EAC7B,CAAS,EACT,CAAS,EACT,EAAU,EACV,EAAU,EACV,GAAsB;IAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,kBAAkB,CAChC,KAA6B,EAC7B,MAA6B,EAC7B,GAAsB;IAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,mBAAmB,CAAC,KAA6B,EAAE,EAAmB;IACpF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,oGAAoG;AACpG,qGAAqG;AACrG,sGAAsG;AACtG,oBAAoB;AACpB,MAAM,UAAU,mBAAmB,CACjC,KAA6B,EAC7B,EAAmB,EACnB,MAA6B;IAE7B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,qGAAqG;AACrG,qGAAqG;AACrG,MAAM,yBAAyB,GAAG,GAAG,CAAC"}
1
+ {"version":3,"file":"spatialIndex.js","sourceRoot":"","sources":["../src/spatialIndex.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,iCAAiC,EAAE,MAAM,eAAe,CAAC;AAElE,gFAAgF;AAChF,MAAM,UAAU,mBAAmB,CAAC,KAA+B;IACjE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;AAC5C,CAAC;AAED,yFAAyF;AACzF,kGAAkG;AAClG,mGAAmG;AACnG,4DAA4D;AAC5D,MAAM,UAAU,oBAAoB,CAAC,OAA+B;IAClE,OAAO;QACL,OAAO,EAAE;YACP,OAAO,EAAE,OAAO,IAAI,iCAAiC,CAAC,yBAAyB,CAAC;SACjF;KACF,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,4FAA4F;AAC5F,iGAAiG;AACjG,kGAAkG;AAClG,6EAA6E;AAC7E,MAAM,UAAU,qBAAqB,CACnC,KAA+B,EAC/B,EAAmB,EACnB,MAA+B;IAE/B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,mGAAmG;AACnG,iGAAiG;AACjG,8FAA8F;AAC9F,MAAM,UAAU,mBAAmB,CAAC,KAA+B,EAAE,GAAkB;IACrF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAC/C,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,mBAAmB,CACjC,KAA+B,EAC/B,CAAS,EACT,CAAS,EACT,GAAsB;IAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;AACrD,CAAC;AAED,iGAAiG;AACjG,kGAAkG;AAClG,MAAM,UAAU,iBAAiB,CAC/B,KAA+B,EAC/B,CAAS,EACT,CAAS,EACT,EAAU,EACV,EAAU,EACV,GAAsB;IAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,oBAAoB,CAClC,KAA+B,EAC/B,MAA+B,EAC/B,GAAsB;IAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,qBAAqB,CAAC,KAA+B,EAAE,EAAmB;IACxF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,oGAAoG;AACpG,uGAAuG;AACvG,sGAAsG;AACtG,oBAAoB;AACpB,MAAM,UAAU,qBAAqB,CACnC,KAA+B,EAC/B,EAAmB,EACnB,MAA+B;IAE/B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,uGAAuG;AACvG,qGAAqG;AACrG,MAAM,yBAAyB,GAAG,GAAG,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { SpatialAabb3D, SpatialFrustum3D, SpatialIndex3D, SpatialIndexBackend3D, SpatialObjectId, SpatialPair } from '@flighthq/types/contract';
2
+ export declare function clearSpatialIndex3D(index: Readonly<SpatialIndex3D>): void;
3
+ export declare function createSpatialIndex3D(backend?: SpatialIndexBackend3D): SpatialIndex3D;
4
+ export declare function insertSpatialObject3D(index: Readonly<SpatialIndex3D>, id: SpatialObjectId, bounds: Readonly<SpatialAabb3D>): boolean;
5
+ export declare function querySpatialFrustum3D(index: Readonly<SpatialIndex3D>, frustum: Readonly<SpatialFrustum3D>, out: SpatialObjectId[], slices?: number): void;
6
+ export declare function querySpatialPairs3D(index: Readonly<SpatialIndex3D>, out: SpatialPair[]): void;
7
+ export declare function querySpatialPoint3D(index: Readonly<SpatialIndex3D>, x: number, y: number, z: number, out: SpatialObjectId[]): void;
8
+ export declare function querySpatialRay3D(index: Readonly<SpatialIndex3D>, x: number, y: number, z: number, dx: number, dy: number, dz: number, out: SpatialObjectId[]): void;
9
+ export declare function querySpatialRegion3D(index: Readonly<SpatialIndex3D>, region: Readonly<SpatialAabb3D>, out: SpatialObjectId[]): void;
10
+ export declare function querySpatialSphere3D(index: Readonly<SpatialIndex3D>, x: number, y: number, z: number, radius: number, out: SpatialObjectId[]): void;
11
+ export declare function removeSpatialObject3D(index: Readonly<SpatialIndex3D>, id: SpatialObjectId): void;
12
+ export declare function updateSpatialObject3D(index: Readonly<SpatialIndex3D>, id: SpatialObjectId, bounds: Readonly<SpatialAabb3D>): boolean;
13
+ //# sourceMappingURL=spatialIndex3D.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spatialIndex3D.d.ts","sourceRoot":"","sources":["../src/spatialIndex3D.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAKlC,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,IAAI,CAEzE;AAMD,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,cAAc,CAMpF;AAOD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,GAC9B,OAAO,CAET;AAmBD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,OAAO,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EACnC,GAAG,EAAE,eAAe,EAAE,EACtB,MAAM,SAAyB,GAC9B,IAAI,CAqDN;AAKD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,IAAI,CAE7F;AAGD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,GAAG,EAAE,eAAe,EAAE,GACrB,IAAI,CAEN;AAKD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,eAAe,EAAE,GACrB,IAAI,CAEN;AAGD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC/B,GAAG,EAAE,eAAe,EAAE,GACrB,IAAI,CAEN;AASD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,eAAe,EAAE,GACrB,IAAI,CAUN;AAGD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,eAAe,GAAG,IAAI,CAEhG;AAMD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC/B,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,GAC9B,OAAO,CAET"}
@@ -0,0 +1,166 @@
1
+ import { createUniformGridSpatialBackend3D } from './uniformGrid3D';
2
+ // Empties the index of all objects while keeping it (and its backend) reusable.
3
+ export function clearSpatialIndex3D(index) {
4
+ index.runtime.backend.clearSpatialIndex();
5
+ }
6
+ // Creates a 3D broadphase index. With no backend it defaults to a uniform grid sized for
7
+ // medium-scale scenes; pass an explicit backend (a differently-sized grid, or a future octree / BVH)
8
+ // to select the structure for the workload. Constructing the default grid happens here, on call —
9
+ // importing the package has no side effect.
10
+ export function createSpatialIndex3D(backend) {
11
+ return {
12
+ runtime: {
13
+ backend: backend ?? createUniformGridSpatialBackend3D(DEFAULT_SPATIAL_CELL_SIZE_3D),
14
+ },
15
+ };
16
+ }
17
+ // Adds an object to the index under `id` with its current bounds. The bounds are copied; the caller
18
+ // may reuse its own value afterward. Returns false when the bounds cannot be indexed at all
19
+ // (non-finite or inverted) — the object is then absent from every query rather than present at a
20
+ // nonsense position. Oversized-but-valid bounds return true and stay fully queryable; the backend
21
+ // decides how to hold them. explainSpatialIndexing3D reports which happened.
22
+ export function insertSpatialObject3D(index, id, bounds) {
23
+ return index.runtime.backend.insertSpatialObject(id, bounds);
24
+ }
25
+ // Fills `out` (cleared first) with the ids whose bounds may lie inside the view volume — the candidate
26
+ // set for view culling.
27
+ //
28
+ // Built on the region query rather than on a new backend method, so every present and future backend
29
+ // answers it without implementing anything, and the ratified eight-method seam does not widen for a
30
+ // query that needs no structural knowledge.
31
+ //
32
+ // The volume is covered by `slices` axis-aligned boxes taken along its DEPTH rather than by one box
33
+ // around the whole thing. A single AABB is correct but nearly useless for culling: a long perspective
34
+ // frustum's bounding box approaches the whole world, so the query would hand back almost every object
35
+ // and cull nothing. Slicing costs one region query per slice and shrinks the covered volume toward the
36
+ // frustum itself — eight slices is a good default, and more is a straight trade of query time against
37
+ // candidates the caller would otherwise reject.
38
+ //
39
+ // The result is a CANDIDATE set, in the same sense as `querySpatialPairs3D`: every id whose bounds the
40
+ // covering boxes touch, which is a superset of what is truly visible. The caller applies the exact
41
+ // plane test to what comes back.
42
+ export function querySpatialFrustum3D(index, frustum, out, slices = DEFAULT_FRUSTUM_SLICES) {
43
+ out.length = 0;
44
+ const corners = frustum.corners;
45
+ if (corners.length < 24 || !(slices >= 1))
46
+ return;
47
+ const steps = Math.floor(slices);
48
+ frustumSeen.clear();
49
+ for (let slice = 0; slice < steps; slice += 1) {
50
+ const nearT = slice / steps;
51
+ const farT = (slice + 1) / steps;
52
+ let minX = Infinity;
53
+ let minY = Infinity;
54
+ let minZ = Infinity;
55
+ let maxX = -Infinity;
56
+ let maxY = -Infinity;
57
+ let maxZ = -Infinity;
58
+ // Both ends of the slice, for all four edges: the volume between two depths is bounded by the eight
59
+ // points at those depths. Taking only the far end would clip the slice's own near face away.
60
+ for (let corner = 0; corner < 4; corner += 1) {
61
+ const near = corner * 3;
62
+ const far = 12 + corner * 3;
63
+ for (const t of [nearT, farT]) {
64
+ const x = corners[near] + (corners[far] - corners[near]) * t;
65
+ const y = corners[near + 1] + (corners[far + 1] - corners[near + 1]) * t;
66
+ const z = corners[near + 2] + (corners[far + 2] - corners[near + 2]) * t;
67
+ if (x < minX)
68
+ minX = x;
69
+ if (x > maxX)
70
+ maxX = x;
71
+ if (y < minY)
72
+ minY = y;
73
+ if (y > maxY)
74
+ maxY = y;
75
+ if (z < minZ)
76
+ minZ = z;
77
+ if (z > maxZ)
78
+ maxZ = z;
79
+ }
80
+ }
81
+ if (!Number.isFinite(minX) || !Number.isFinite(maxZ))
82
+ return;
83
+ queryRegionScratch.minX = minX;
84
+ queryRegionScratch.minY = minY;
85
+ queryRegionScratch.minZ = minZ;
86
+ queryRegionScratch.maxX = maxX;
87
+ queryRegionScratch.maxY = maxY;
88
+ queryRegionScratch.maxZ = maxZ;
89
+ index.runtime.backend.querySpatialRegion(queryRegionScratch, frustumSlice);
90
+ // Slices share objects that straddle their boundary, so the union has to be deduplicated — without
91
+ // this the same id appears once per slice it touches, and a caller counting results would over-count
92
+ // a large object exactly in proportion to how large it is.
93
+ for (const id of frustumSlice) {
94
+ if (frustumSeen.has(id))
95
+ continue;
96
+ frustumSeen.add(id);
97
+ out.push(id);
98
+ }
99
+ }
100
+ }
101
+ // Fills `out` (cleared first) with every deduplicated candidate pair — each unordered pair at most
102
+ // once, never an object with itself. A pair is a broadphase candidate: the two objects are close
103
+ // enough to be worth a narrow-phase test, which the caller (or @flighthq/collision) performs.
104
+ export function querySpatialPairs3D(index, out) {
105
+ index.runtime.backend.querySpatialPairs(out);
106
+ }
107
+ // Fills `out` (cleared first) with the ids whose bounds contain the point (`x`,`y`,`z`).
108
+ export function querySpatialPoint3D(index, x, y, z, out) {
109
+ index.runtime.backend.querySpatialPoint(x, y, z, out);
110
+ }
111
+ // Fills `out` (cleared first) with the ids whose bounds the ray from (`x`,`y`,`z`) along
112
+ // (`dx`,`dy`,`dz`) intersects. The direction need not be normalized; the ray is treated as extending
113
+ // forward only.
114
+ export function querySpatialRay3D(index, x, y, z, dx, dy, dz, out) {
115
+ index.runtime.backend.querySpatialRay(x, y, z, dx, dy, dz, out);
116
+ }
117
+ // Fills `out` (cleared first) with the ids whose bounds overlap `region`.
118
+ export function querySpatialRegion3D(index, region, out) {
119
+ index.runtime.backend.querySpatialRegion(region, out);
120
+ }
121
+ // Fills `out` (cleared first) with the ids whose bounds may lie within `radius` of (`x`,`y`,`z`).
122
+ //
123
+ // A CANDIDATE set over the sphere's bounding cube, not an exact sphere test — the index stores bounds
124
+ // and answers box questions, and the corners of that cube reach past the sphere by a factor of the
125
+ // square root of three. That is the same contract every other query here keeps, and the caller that
126
+ // needs exactness applies the distance test to what comes back. The value of the export is that the
127
+ // cube is derived once, correctly, instead of at every callsite.
128
+ export function querySpatialSphere3D(index, x, y, z, radius, out) {
129
+ out.length = 0;
130
+ if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z) || !(radius >= 0))
131
+ return;
132
+ queryRegionScratch.minX = x - radius;
133
+ queryRegionScratch.minY = y - radius;
134
+ queryRegionScratch.minZ = z - radius;
135
+ queryRegionScratch.maxX = x + radius;
136
+ queryRegionScratch.maxY = y + radius;
137
+ queryRegionScratch.maxZ = z + radius;
138
+ index.runtime.backend.querySpatialRegion(queryRegionScratch, out);
139
+ }
140
+ // Removes an object from the index. A no-op if the id is not present.
141
+ export function removeSpatialObject3D(index, id) {
142
+ index.runtime.backend.removeSpatialObject(id);
143
+ }
144
+ // Moves an already-inserted object to new bounds. Inserting a not-yet-present id behaves as insert.
145
+ // Returns the same sentinel as insertSpatialObject3D. A declined update removes the object rather than
146
+ // leaving it at its old bounds, so a caller that ignores the sentinel can never read a stale position
147
+ // as a current one.
148
+ export function updateSpatialObject3D(index, id, bounds) {
149
+ return index.runtime.backend.updateSpatialObject(id, bounds);
150
+ }
151
+ // The default uniform-grid cell size when createSpatialIndex3D is called without an explicit backend.
152
+ // Deliberately the same middle-of-the-road number as the 2D default: a cell is a world-space length,
153
+ // not a volume, so "roughly the size of a typical object" means the same thing in both dimensions. A
154
+ // workload with a known typical object size should pass its own grid — and in 3D it pays off sooner,
155
+ // since the per-object cell budget is a ~10-cell cube rather than a 32-cell square.
156
+ const DEFAULT_SPATIAL_CELL_SIZE_3D = 128;
157
+ // How many depth slices cover a frustum when the caller does not choose. Eight brings a typical
158
+ // perspective volume's covered bounds close to the volume itself while keeping the query to eight
159
+ // region calls; one slice degenerates to the single-AABB behaviour that makes frustum culling pointless.
160
+ const DEFAULT_FRUSTUM_SLICES = 8;
161
+ // Reused across calls: a culling pass runs every frame, and these would otherwise be three allocations
162
+ // per frame in the hot path. Never held beyond the call that fills them.
163
+ const queryRegionScratch = { maxX: 0, maxY: 0, maxZ: 0, minX: 0, minY: 0, minZ: 0 };
164
+ const frustumSeen = new Set();
165
+ const frustumSlice = [];
166
+ //# sourceMappingURL=spatialIndex3D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spatialIndex3D.js","sourceRoot":"","sources":["../src/spatialIndex3D.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { SpatialIndexingGuard, SpatialIndexingNotice } from '@flighthq/types/contract';
2
+ export declare function reportSpatialIndexing(notice: Readonly<SpatialIndexingNotice>): void;
3
+ export declare function setSpatialIndexingGuard(guard: SpatialIndexingGuard | null): void;
4
+ //# sourceMappingURL=spatialIndexingGuard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spatialIndexingGuard.d.ts","sourceRoot":"","sources":["../src/spatialIndexingGuard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAU5F,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,IAAI,CAGnF;AAMD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAEhF"}
@@ -0,0 +1,23 @@
1
+ // Hands a notice to the installed guard, or does nothing when none is installed. The null check is
2
+ // all production pays at a noteworthy site; the caller-facing text lives in the separately-importable
3
+ // formatSpatialIndexingNotice, per the diagnostics inversion rule.
4
+ //
5
+ // Shared by both dimensions' grids on purpose. The guard is a development diagnostic keyed to the
6
+ // question "why is this object not in my query results?", which is dimension-free — the notice's own
7
+ // vocabulary (mode, operation, reason, bucketCount) carries no axis. Giving 2D and 3D separate guards
8
+ // would mean an application debugging an index had to install two.
9
+ export function reportSpatialIndexing(notice) {
10
+ if (_indexingGuard === null)
11
+ return;
12
+ _indexingGuard(notice);
13
+ }
14
+ // Installs the indexing guard consulted for invalid configuration or bounds, missing-id operations,
15
+ // and overflow routing; null uninstalls it. Module-scoped rather than per-grid: it is a development
16
+ // diagnostic, and an application debugging an index wants it on for every grid at once — in either
17
+ // dimension.
18
+ export function setSpatialIndexingGuard(guard) {
19
+ _indexingGuard = guard;
20
+ }
21
+ // Diagnostics seam filled by setSpatialIndexingGuard.
22
+ let _indexingGuard = null;
23
+ //# sourceMappingURL=spatialIndexingGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spatialIndexingGuard.js","sourceRoot":"","sources":["../src/spatialIndexingGuard.ts"],"names":[],"mappings":"AAEA,mGAAmG;AACnG,sGAAsG;AACtG,mEAAmE;AACnE,EAAE;AACF,kGAAkG;AAClG,qGAAqG;AACrG,sGAAsG;AACtG,mEAAmE;AACnE,MAAM,UAAU,qBAAqB,CAAC,MAAuC;IAC3E,IAAI,cAAc,KAAK,IAAI;QAAE,OAAO;IACpC,cAAc,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC;AAED,oGAAoG;AACpG,oGAAoG;AACpG,mGAAmG;AACnG,aAAa;AACb,MAAM,UAAU,uBAAuB,CAAC,KAAkC;IACxE,cAAc,GAAG,KAAK,CAAC;AACzB,CAAC;AAED,sDAAsD;AACtD,IAAI,cAAc,GAAgC,IAAI,CAAC"}
@@ -1,5 +1,4 @@
1
- import type { SpatialIndexBackend, SpatialIndexingGuard } from '@flighthq/types/contract';
1
+ import type { SpatialIndexBackend2D } from '@flighthq/types/contract';
2
2
  export declare const MAX_INDEXED_CELLS_PER_OBJECT = 1024;
3
- export declare function createUniformGridSpatialBackend(cellSize: number): SpatialIndexBackend;
4
- export declare function setSpatialIndexingGuard(guard: SpatialIndexingGuard | null): void;
3
+ export declare function createUniformGridSpatialBackend2D(cellSize: number): SpatialIndexBackend2D;
5
4
  //# sourceMappingURL=uniformGrid.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uniformGrid.d.ts","sourceRoot":"","sources":["../src/uniformGrid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,mBAAmB,EAGnB,oBAAoB,EAMrB,MAAM,0BAA0B,CAAC;AAiBlC,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAejD,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CAkDrF;AAKD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAEhF"}
1
+ {"version":3,"file":"uniformGrid.d.ts","sourceRoot":"","sources":["../src/uniformGrid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,qBAAqB,EAQtB,MAAM,0BAA0B,CAAC;AAmBlC,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAejD,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CAkDzF"}
@@ -1,3 +1,4 @@
1
+ import { reportSpatialIndexing } from './spatialIndexingGuard';
1
2
  // The per-object cell budget. An object whose AABB covers more cells than this is held in the flat
2
3
  // overflow list instead of being written into every cell it spans.
3
4
  //
@@ -21,13 +22,13 @@ export const MAX_INDEXED_CELLS_PER_OBJECT = 1024;
21
22
  // good value is a positive finite number roughly the size of a typical object (too small over-spans
22
23
  // large objects across many cells, too large lumps unrelated objects together). An invalid size uses
23
24
  // the bounded overflow path to keep results correct and reports through the indexing guard. No
24
- // import-time side effect — the caller constructs a grid explicitly, and createSpatialIndex uses
25
+ // import-time side effect — the caller constructs a grid explicitly, and createSpatialIndex2D uses
25
26
  // this as its default index.
26
27
  //
27
28
  // Object size does not set the cost: an AABB spanning more than MAX_INDEXED_CELLS_PER_OBJECT cells
28
29
  // goes to a flat overflow list that every query scans, and non-finite or inverted bounds are declined
29
- // outright with a false sentinel. Both are visible through explainSpatialIndexing.
30
- export function createUniformGridSpatialBackend(cellSize) {
30
+ // outright with a false sentinel. Both are visible through explainSpatialIndexing2D.
31
+ export function createUniformGridSpatialBackend2D(cellSize) {
31
32
  const grid = {
32
33
  cellSize,
33
34
  cells: new Map(),
@@ -79,12 +80,6 @@ export function createUniformGridSpatialBackend(cellSize) {
79
80
  },
80
81
  };
81
82
  }
82
- // Installs the indexing guard consulted for invalid configuration or bounds, missing-id operations,
83
- // and overflow routing; null uninstalls it. Module-scoped rather than per-grid: it is a development
84
- // diagnostic, and an application debugging an index wants it on for every grid at once.
85
- export function setSpatialIndexingGuard(guard) {
86
- _indexingGuard = guard;
87
- }
88
83
  // Maps a world coordinate to its cell index along one axis. Uses floor so negative coordinates map
89
84
  // to consistently decreasing cell indices (world 0 is the boundary between cell -1 and cell 0).
90
85
  function _cellIndex(coord, cellSize) {
@@ -387,9 +382,7 @@ function _queryGridPairs(grid, out) {
387
382
  _queryGridOverflowPairs(grid, out);
388
383
  }
389
384
  function _reportGridIndexing(grid, id, mode, operation, reason, wouldOccupyBucketCount) {
390
- if (_indexingGuard === null)
391
- return;
392
- _indexingGuard({ cellSize: grid.cellSize, id, mode, operation, reason, wouldOccupyBucketCount });
385
+ reportSpatialIndexing({ cellSize: grid.cellSize, id, mode, operation, reason, wouldOccupyBucketCount });
393
386
  }
394
387
  // Gathers the ids in the cell containing the point, then confirms each against its real bounds. A
395
388
  // single cell holds each id at most once, so no dedup pass is needed. Overflowed objects hold no cell
@@ -560,7 +553,4 @@ function _spannedCellCount(cellSize, aabb) {
560
553
  const cy1 = _cellIndex(aabb.maxY, cellSize);
561
554
  return (cx1 - cx0 + 1) * (cy1 - cy0 + 1);
562
555
  }
563
- // Diagnostics seam filled by setSpatialIndexingGuard. Caller-facing text stays in the separate
564
- // formatSpatialIndexingNotice module, so production pays only the null checks at noteworthy sites.
565
- let _indexingGuard = null;
566
556
  //# sourceMappingURL=uniformGrid.js.map