@spatial-engine/three 0.0.3 → 0.0.4
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/dist/index.cjs +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/synchronizer.ts"],"sourcesContent":["import type { Box3, Ray } from 'three';\nimport { AABBPool, RayPool, rayIntersectsAABB, RAY_STRIDE } from '@spatial-engine/core';\n\nexport { ThreeSynchronizer } from './synchronizer.js';\n\n/**\n * Convert a Three.js Box3 into an AABB slot in the pool.\n * Returns the allocated index.\n */\nexport function box3ToAABB(pool: AABBPool, box: Box3): number {\n const index = pool.allocate();\n pool.set(\n index,\n box.min.x,\n box.min.y,\n box.min.z,\n box.max.x,\n box.max.y,\n box.max.z,\n );\n return index;\n}\n\n/**\n * Convert a Three.js Ray into a Ray slot in the pool.\n * Returns the allocated index.\n */\nexport function threeRayToPool(pool: RayPool, ray: Ray): number {\n const index = pool.allocate();\n pool.set(\n index,\n ray.origin.x,\n ray.origin.y,\n ray.origin.z,\n ray.direction.x,\n ray.direction.y,\n ray.direction.z,\n );\n return index;\n}\n\n/**\n * Fill a pre-allocated (or newly created) Float32Array with the ray data in\n * the flat format `[ox, oy, oz, dx, dy, dz]` expected by the core query engine.\n *\n * @param ray The Three.js Ray to convert.\n * @param buf Optional pre-allocated Float32Array of length RAY_STRIDE (6).\n * If omitted a new buffer is created. Pass a cached buffer to\n * avoid allocation and stay zero-GC.\n * @returns The filled buffer (same reference as `buf` when provided).\n */\nexport function rayToFlatArray(ray: Ray, buf: Float32Array = new Float32Array(RAY_STRIDE)): Float32Array {\n buf[0] = ray.origin.x;\n buf[1] = ray.origin.y;\n buf[2] = ray.origin.z;\n buf[3] = ray.direction.x;\n buf[4] = ray.direction.y;\n buf[5] = ray.direction.z;\n return buf;\n}\n\n/**\n * Test whether a Three.js Ray intersects a Three.js Box3.\n * Returns the parametric hit distance `t` or -1 on miss.\n * Uses pre-allocated Float32Array buffers to stay zero-GC.\n */\nconst _rayBuf = new Float32Array(RAY_STRIDE);\nconst _aabbBuf = new Float32Array(6);\n\nexport function rayBox3Intersect(ray: Ray, box: Box3): number {\n _rayBuf[0] = ray.origin.x;\n _rayBuf[1] = ray.origin.y;\n _rayBuf[2] = ray.origin.z;\n _rayBuf[3] = ray.direction.x;\n _rayBuf[4] = ray.direction.y;\n _rayBuf[5] = ray.direction.z;\n\n _aabbBuf[0] = box.min.x;\n _aabbBuf[1] = box.min.y;\n _aabbBuf[2] = box.min.z;\n _aabbBuf[3] = box.max.x;\n _aabbBuf[4] = box.max.y;\n _aabbBuf[5] = box.max.z;\n\n return rayIntersectsAABB(_rayBuf, 0, _aabbBuf, 0);\n}\n","import type { Mesh, Group } from 'three';\nimport { Box3 } from 'three';\nimport { AABBPool, Octree } from '@spatial-engine/core';\n\n/**\n * Synchronizes a THREE.Mesh or THREE.Group with a spatial-engine Octree.\n *\n * On the first call to `sync()` the object's world-space bounding box is\n * computed, stored in the AABBPool, and inserted into the Octree.\n * Subsequent calls to `sync()` recompute the bounding box and call\n * `Octree.update()` to reposition the entry without a full reinsertion.\n *\n * Each synchronizer occupies exactly one slot in the supplied AABBPool;\n * that slot's index is exposed as the read-only `id` property.\n */\nexport class ThreeSynchronizer {\n /** The AABBPool index used to identify this object in the core engine. */\n readonly id: number;\n\n private readonly object: Mesh | Group;\n private readonly octree: Octree;\n private readonly aabbPool: AABBPool;\n private readonly _box: Box3 = new Box3();\n private _inserted: boolean = false;\n private _disposed: boolean = false;\n\n constructor(object: Mesh | Group, octree: Octree, aabbPool: AABBPool) {\n this.object = object;\n this.octree = octree;\n this.aabbPool = aabbPool;\n this.id = aabbPool.allocate();\n }\n\n /**\n * Recompute the object's world-space bounding box and sync it to the\n * Octree. Call this whenever the object may have moved or changed shape.\n */\n sync(): void {\n if (this._disposed) return;\n this._box.setFromObject(this.object);\n const { min, max } = this._box;\n\n if (!this._inserted) {\n this.aabbPool.set(this.id, min.x, min.y, min.z, max.x, max.y, max.z);\n this.octree.insert(this.id);\n this._inserted = true;\n } else {\n this.octree.update(this.id, min.x, min.y, min.z, max.x, max.y, max.z);\n }\n }\n\n /**\n * Remove this object from the octree and mark the synchronizer as\n * disposed. After calling this, further `sync()` calls are no-ops.\n */\n dispose(): void {\n if (this._disposed) return;\n this._disposed = true;\n if (this._inserted) {\n this.octree.remove(this.id);\n this._inserted = false;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAiE;;;ACAjE,mBAAqB;AAcd,IAAM,oBAAN,MAAwB;AAAA;AAAA,EAEpB;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAa,IAAI,kBAAK;AAAA,EAC/B,YAAqB;AAAA,EACrB,YAAqB;AAAA,EAE7B,YAAY,QAAsB,QAAgB,UAAoB;AACpE,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,KAAK,SAAS,SAAS;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAa;AACX,QAAI,KAAK,UAAW;AACpB,SAAK,KAAK,cAAc,KAAK,MAAM;AACnC,UAAM,EAAE,KAAK,IAAI,IAAI,KAAK;AAE1B,QAAI,CAAC,KAAK,WAAW;AACnB,WAAK,SAAS,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACnE,WAAK,OAAO,OAAO,KAAK,EAAE;AAC1B,WAAK,YAAY;AAAA,IACnB,OAAO;AACL,WAAK,OAAO,OAAO,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAAA,IACtE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAgB;AACd,QAAI,KAAK,UAAW;AACpB,SAAK,YAAY;AACjB,QAAI,KAAK,WAAW;AAClB,WAAK,OAAO,OAAO,KAAK,EAAE;AAC1B,WAAK,YAAY;AAAA,IACnB;AAAA,
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/synchronizer.ts"],"sourcesContent":["import type { Box3, Ray } from 'three';\nimport { AABBPool, RayPool, rayIntersectsAABB, RAY_STRIDE } from '@spatial-engine/core';\n\nexport { ThreeSynchronizer } from './synchronizer.js';\n\n/**\n * Convert a Three.js Box3 into an AABB slot in the pool.\n * Returns the allocated index.\n */\nexport function box3ToAABB(pool: AABBPool, box: Box3): number {\n const index = pool.allocate();\n pool.set(\n index,\n box.min.x,\n box.min.y,\n box.min.z,\n box.max.x,\n box.max.y,\n box.max.z,\n );\n return index;\n}\n\n/**\n * Convert a Three.js Ray into a Ray slot in the pool.\n * Returns the allocated index.\n */\nexport function threeRayToPool(pool: RayPool, ray: Ray): number {\n const index = pool.allocate();\n pool.set(\n index,\n ray.origin.x,\n ray.origin.y,\n ray.origin.z,\n ray.direction.x,\n ray.direction.y,\n ray.direction.z,\n );\n return index;\n}\n\n/**\n * Fill a pre-allocated (or newly created) Float32Array with the ray data in\n * the flat format `[ox, oy, oz, dx, dy, dz]` expected by the core query engine.\n *\n * @param ray The Three.js Ray to convert.\n * @param buf Optional pre-allocated Float32Array of length RAY_STRIDE (6).\n * If omitted a new buffer is created. Pass a cached buffer to\n * avoid allocation and stay zero-GC.\n * @returns The filled buffer (same reference as `buf` when provided).\n */\nexport function rayToFlatArray(ray: Ray, buf: Float32Array = new Float32Array(RAY_STRIDE)): Float32Array {\n buf[0] = ray.origin.x;\n buf[1] = ray.origin.y;\n buf[2] = ray.origin.z;\n buf[3] = ray.direction.x;\n buf[4] = ray.direction.y;\n buf[5] = ray.direction.z;\n return buf;\n}\n\n/**\n * Test whether a Three.js Ray intersects a Three.js Box3.\n * Returns the parametric hit distance `t` or -1 on miss.\n * Uses pre-allocated Float32Array buffers to stay zero-GC.\n */\nconst _rayBuf = new Float32Array(RAY_STRIDE);\nconst _aabbBuf = new Float32Array(6);\n\nexport function rayBox3Intersect(ray: Ray, box: Box3): number {\n _rayBuf[0] = ray.origin.x;\n _rayBuf[1] = ray.origin.y;\n _rayBuf[2] = ray.origin.z;\n _rayBuf[3] = ray.direction.x;\n _rayBuf[4] = ray.direction.y;\n _rayBuf[5] = ray.direction.z;\n\n _aabbBuf[0] = box.min.x;\n _aabbBuf[1] = box.min.y;\n _aabbBuf[2] = box.min.z;\n _aabbBuf[3] = box.max.x;\n _aabbBuf[4] = box.max.y;\n _aabbBuf[5] = box.max.z;\n\n return rayIntersectsAABB(_rayBuf, 0, _aabbBuf, 0);\n}\n","import type { Mesh, Group } from 'three';\nimport { Box3 } from 'three';\nimport { AABBPool, Octree } from '@spatial-engine/core';\n\n/**\n * Synchronizes a THREE.Mesh or THREE.Group with a spatial-engine Octree.\n *\n * On the first call to `sync()` the object's world-space bounding box is\n * computed, stored in the AABBPool, and inserted into the Octree.\n * Subsequent calls to `sync()` recompute the bounding box and call\n * `Octree.update()` to reposition the entry without a full reinsertion.\n *\n * Each synchronizer occupies exactly one slot in the supplied AABBPool;\n * that slot's index is exposed as the read-only `id` property.\n */\nexport class ThreeSynchronizer {\n /** The AABBPool index used to identify this object in the core engine. */\n readonly id: number;\n\n private readonly object: Mesh | Group;\n private readonly octree: Octree;\n private readonly aabbPool: AABBPool;\n private readonly _box: Box3 = new Box3();\n private _inserted: boolean = false;\n private _disposed: boolean = false;\n\n constructor(object: Mesh | Group, octree: Octree, aabbPool: AABBPool) {\n this.object = object;\n this.octree = octree;\n this.aabbPool = aabbPool;\n this.id = aabbPool.allocate();\n }\n\n /**\n * Recompute the object's world-space bounding box and sync it to the\n * Octree. Call this whenever the object may have moved or changed shape.\n */\n sync(): void {\n if (this._disposed) return;\n this._box.setFromObject(this.object);\n const { min, max } = this._box;\n\n if (!this._inserted) {\n this.aabbPool.set(this.id, min.x, min.y, min.z, max.x, max.y, max.z);\n this.octree.insert(this.id);\n this._inserted = true;\n } else {\n this.octree.update(this.id, min.x, min.y, min.z, max.x, max.y, max.z);\n }\n }\n\n /**\n * Remove this object from the octree and mark the synchronizer as\n * disposed. After calling this, further `sync()` calls are no-ops.\n */\n dispose(): void {\n if (this._disposed) return;\n this._disposed = true;\n if (this._inserted) {\n this.octree.remove(this.id);\n this._inserted = false;\n }\n // Return the AABBPool slot so it can be reused by the next synchronizer.\n this.aabbPool.release(this.id);\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/synchronizer.ts"],"sourcesContent":["import type { Box3, Ray } from 'three';\nimport { AABBPool, RayPool, rayIntersectsAABB, RAY_STRIDE } from '@spatial-engine/core';\n\nexport { ThreeSynchronizer } from './synchronizer.js';\n\n/**\n * Convert a Three.js Box3 into an AABB slot in the pool.\n * Returns the allocated index.\n */\nexport function box3ToAABB(pool: AABBPool, box: Box3): number {\n const index = pool.allocate();\n pool.set(\n index,\n box.min.x,\n box.min.y,\n box.min.z,\n box.max.x,\n box.max.y,\n box.max.z,\n );\n return index;\n}\n\n/**\n * Convert a Three.js Ray into a Ray slot in the pool.\n * Returns the allocated index.\n */\nexport function threeRayToPool(pool: RayPool, ray: Ray): number {\n const index = pool.allocate();\n pool.set(\n index,\n ray.origin.x,\n ray.origin.y,\n ray.origin.z,\n ray.direction.x,\n ray.direction.y,\n ray.direction.z,\n );\n return index;\n}\n\n/**\n * Fill a pre-allocated (or newly created) Float32Array with the ray data in\n * the flat format `[ox, oy, oz, dx, dy, dz]` expected by the core query engine.\n *\n * @param ray The Three.js Ray to convert.\n * @param buf Optional pre-allocated Float32Array of length RAY_STRIDE (6).\n * If omitted a new buffer is created. Pass a cached buffer to\n * avoid allocation and stay zero-GC.\n * @returns The filled buffer (same reference as `buf` when provided).\n */\nexport function rayToFlatArray(ray: Ray, buf: Float32Array = new Float32Array(RAY_STRIDE)): Float32Array {\n buf[0] = ray.origin.x;\n buf[1] = ray.origin.y;\n buf[2] = ray.origin.z;\n buf[3] = ray.direction.x;\n buf[4] = ray.direction.y;\n buf[5] = ray.direction.z;\n return buf;\n}\n\n/**\n * Test whether a Three.js Ray intersects a Three.js Box3.\n * Returns the parametric hit distance `t` or -1 on miss.\n * Uses pre-allocated Float32Array buffers to stay zero-GC.\n */\nconst _rayBuf = new Float32Array(RAY_STRIDE);\nconst _aabbBuf = new Float32Array(6);\n\nexport function rayBox3Intersect(ray: Ray, box: Box3): number {\n _rayBuf[0] = ray.origin.x;\n _rayBuf[1] = ray.origin.y;\n _rayBuf[2] = ray.origin.z;\n _rayBuf[3] = ray.direction.x;\n _rayBuf[4] = ray.direction.y;\n _rayBuf[5] = ray.direction.z;\n\n _aabbBuf[0] = box.min.x;\n _aabbBuf[1] = box.min.y;\n _aabbBuf[2] = box.min.z;\n _aabbBuf[3] = box.max.x;\n _aabbBuf[4] = box.max.y;\n _aabbBuf[5] = box.max.z;\n\n return rayIntersectsAABB(_rayBuf, 0, _aabbBuf, 0);\n}\n","import type { Mesh, Group } from 'three';\nimport { Box3 } from 'three';\nimport { AABBPool, Octree } from '@spatial-engine/core';\n\n/**\n * Synchronizes a THREE.Mesh or THREE.Group with a spatial-engine Octree.\n *\n * On the first call to `sync()` the object's world-space bounding box is\n * computed, stored in the AABBPool, and inserted into the Octree.\n * Subsequent calls to `sync()` recompute the bounding box and call\n * `Octree.update()` to reposition the entry without a full reinsertion.\n *\n * Each synchronizer occupies exactly one slot in the supplied AABBPool;\n * that slot's index is exposed as the read-only `id` property.\n */\nexport class ThreeSynchronizer {\n /** The AABBPool index used to identify this object in the core engine. */\n readonly id: number;\n\n private readonly object: Mesh | Group;\n private readonly octree: Octree;\n private readonly aabbPool: AABBPool;\n private readonly _box: Box3 = new Box3();\n private _inserted: boolean = false;\n private _disposed: boolean = false;\n\n constructor(object: Mesh | Group, octree: Octree, aabbPool: AABBPool) {\n this.object = object;\n this.octree = octree;\n this.aabbPool = aabbPool;\n this.id = aabbPool.allocate();\n }\n\n /**\n * Recompute the object's world-space bounding box and sync it to the\n * Octree. Call this whenever the object may have moved or changed shape.\n */\n sync(): void {\n if (this._disposed) return;\n this._box.setFromObject(this.object);\n const { min, max } = this._box;\n\n if (!this._inserted) {\n this.aabbPool.set(this.id, min.x, min.y, min.z, max.x, max.y, max.z);\n this.octree.insert(this.id);\n this._inserted = true;\n } else {\n this.octree.update(this.id, min.x, min.y, min.z, max.x, max.y, max.z);\n }\n }\n\n /**\n * Remove this object from the octree and mark the synchronizer as\n * disposed. After calling this, further `sync()` calls are no-ops.\n */\n dispose(): void {\n if (this._disposed) return;\n this._disposed = true;\n if (this._inserted) {\n this.octree.remove(this.id);\n this._inserted = false;\n }\n }\n}\n"],"mappings":";AACA,SAA4B,mBAAmB,kBAAkB;;;ACAjE,SAAS,YAAY;AAcd,IAAM,oBAAN,MAAwB;AAAA;AAAA,EAEpB;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAa,IAAI,KAAK;AAAA,EAC/B,YAAqB;AAAA,EACrB,YAAqB;AAAA,EAE7B,YAAY,QAAsB,QAAgB,UAAoB;AACpE,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,KAAK,SAAS,SAAS;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAa;AACX,QAAI,KAAK,UAAW;AACpB,SAAK,KAAK,cAAc,KAAK,MAAM;AACnC,UAAM,EAAE,KAAK,IAAI,IAAI,KAAK;AAE1B,QAAI,CAAC,KAAK,WAAW;AACnB,WAAK,SAAS,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACnE,WAAK,OAAO,OAAO,KAAK,EAAE;AAC1B,WAAK,YAAY;AAAA,IACnB,OAAO;AACL,WAAK,OAAO,OAAO,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAAA,IACtE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAgB;AACd,QAAI,KAAK,UAAW;AACpB,SAAK,YAAY;AACjB,QAAI,KAAK,WAAW;AAClB,WAAK,OAAO,OAAO,KAAK,EAAE;AAC1B,WAAK,YAAY;AAAA,IACnB;AAAA,
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/synchronizer.ts"],"sourcesContent":["import type { Box3, Ray } from 'three';\nimport { AABBPool, RayPool, rayIntersectsAABB, RAY_STRIDE } from '@spatial-engine/core';\n\nexport { ThreeSynchronizer } from './synchronizer.js';\n\n/**\n * Convert a Three.js Box3 into an AABB slot in the pool.\n * Returns the allocated index.\n */\nexport function box3ToAABB(pool: AABBPool, box: Box3): number {\n const index = pool.allocate();\n pool.set(\n index,\n box.min.x,\n box.min.y,\n box.min.z,\n box.max.x,\n box.max.y,\n box.max.z,\n );\n return index;\n}\n\n/**\n * Convert a Three.js Ray into a Ray slot in the pool.\n * Returns the allocated index.\n */\nexport function threeRayToPool(pool: RayPool, ray: Ray): number {\n const index = pool.allocate();\n pool.set(\n index,\n ray.origin.x,\n ray.origin.y,\n ray.origin.z,\n ray.direction.x,\n ray.direction.y,\n ray.direction.z,\n );\n return index;\n}\n\n/**\n * Fill a pre-allocated (or newly created) Float32Array with the ray data in\n * the flat format `[ox, oy, oz, dx, dy, dz]` expected by the core query engine.\n *\n * @param ray The Three.js Ray to convert.\n * @param buf Optional pre-allocated Float32Array of length RAY_STRIDE (6).\n * If omitted a new buffer is created. Pass a cached buffer to\n * avoid allocation and stay zero-GC.\n * @returns The filled buffer (same reference as `buf` when provided).\n */\nexport function rayToFlatArray(ray: Ray, buf: Float32Array = new Float32Array(RAY_STRIDE)): Float32Array {\n buf[0] = ray.origin.x;\n buf[1] = ray.origin.y;\n buf[2] = ray.origin.z;\n buf[3] = ray.direction.x;\n buf[4] = ray.direction.y;\n buf[5] = ray.direction.z;\n return buf;\n}\n\n/**\n * Test whether a Three.js Ray intersects a Three.js Box3.\n * Returns the parametric hit distance `t` or -1 on miss.\n * Uses pre-allocated Float32Array buffers to stay zero-GC.\n */\nconst _rayBuf = new Float32Array(RAY_STRIDE);\nconst _aabbBuf = new Float32Array(6);\n\nexport function rayBox3Intersect(ray: Ray, box: Box3): number {\n _rayBuf[0] = ray.origin.x;\n _rayBuf[1] = ray.origin.y;\n _rayBuf[2] = ray.origin.z;\n _rayBuf[3] = ray.direction.x;\n _rayBuf[4] = ray.direction.y;\n _rayBuf[5] = ray.direction.z;\n\n _aabbBuf[0] = box.min.x;\n _aabbBuf[1] = box.min.y;\n _aabbBuf[2] = box.min.z;\n _aabbBuf[3] = box.max.x;\n _aabbBuf[4] = box.max.y;\n _aabbBuf[5] = box.max.z;\n\n return rayIntersectsAABB(_rayBuf, 0, _aabbBuf, 0);\n}\n","import type { Mesh, Group } from 'three';\nimport { Box3 } from 'three';\nimport { AABBPool, Octree } from '@spatial-engine/core';\n\n/**\n * Synchronizes a THREE.Mesh or THREE.Group with a spatial-engine Octree.\n *\n * On the first call to `sync()` the object's world-space bounding box is\n * computed, stored in the AABBPool, and inserted into the Octree.\n * Subsequent calls to `sync()` recompute the bounding box and call\n * `Octree.update()` to reposition the entry without a full reinsertion.\n *\n * Each synchronizer occupies exactly one slot in the supplied AABBPool;\n * that slot's index is exposed as the read-only `id` property.\n */\nexport class ThreeSynchronizer {\n /** The AABBPool index used to identify this object in the core engine. */\n readonly id: number;\n\n private readonly object: Mesh | Group;\n private readonly octree: Octree;\n private readonly aabbPool: AABBPool;\n private readonly _box: Box3 = new Box3();\n private _inserted: boolean = false;\n private _disposed: boolean = false;\n\n constructor(object: Mesh | Group, octree: Octree, aabbPool: AABBPool) {\n this.object = object;\n this.octree = octree;\n this.aabbPool = aabbPool;\n this.id = aabbPool.allocate();\n }\n\n /**\n * Recompute the object's world-space bounding box and sync it to the\n * Octree. Call this whenever the object may have moved or changed shape.\n */\n sync(): void {\n if (this._disposed) return;\n this._box.setFromObject(this.object);\n const { min, max } = this._box;\n\n if (!this._inserted) {\n this.aabbPool.set(this.id, min.x, min.y, min.z, max.x, max.y, max.z);\n this.octree.insert(this.id);\n this._inserted = true;\n } else {\n this.octree.update(this.id, min.x, min.y, min.z, max.x, max.y, max.z);\n }\n }\n\n /**\n * Remove this object from the octree and mark the synchronizer as\n * disposed. After calling this, further `sync()` calls are no-ops.\n */\n dispose(): void {\n if (this._disposed) return;\n this._disposed = true;\n if (this._inserted) {\n this.octree.remove(this.id);\n this._inserted = false;\n }\n // Return the AABBPool slot so it can be reused by the next synchronizer.\n this.aabbPool.release(this.id);\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spatial-engine/three",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Three.js adapter for @spatial-engine/core",
|
|
5
5
|
"author": "Francisco Rueda Esquivel",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"dist"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@spatial-engine/core": "0.0.
|
|
37
|
+
"@spatial-engine/core": "0.0.4"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"three": ">=0.150.0"
|