{"version":3,"file":"webgpu.cjs","sources":["../../src/core/BatchedMeshBVH.ts","../../src/core/MultiDrawRenderList.ts","../../src/core/feature/ComputeBVH.ts","../../src/utils/SortingUtils.ts","../../src/core/feature/FrustumCulling.ts","../../src/core/feature/GetPositionAt.ts","../../src/core/feature/LOD.ts","../../src/core/feature/Raycasting.ts","../../src/patch/ExtendBatchedMeshPrototype.common.ts","../../src/patch/ExtendBatchedMeshPrototype.webgpu.ts","../../src/patch/PatchBatchedMeshMaterial.ts","../../src/utils/CountUtils.ts"],"sourcesContent":["import { box3ToArray, BVH, BVHNode, HybridBuilder, onFrustumIntersectionCallback, onIntersectionCallback, onIntersectionRayCallback, vec3ToArray, WebGLCoordinateSystem, WebGPUCoordinateSystem } from 'bvh.js';\r\nimport { BatchedMesh, Box3, CoordinateSystem, Matrix4, Raycaster } from 'three';\r\n\r\n// TODO implement getBBoxFromBSphere (add property to geometryInfo)\r\n// TODO implement frustumCullingLOD?\r\n\r\n/**\r\n * Class to manage BVH (Bounding Volume Hierarchy) for `BatchedMesh`.\r\n * Provides methods for managing bounding volumes, frustum culling, raycasting, and bounding box computation.\r\n */\r\nexport class BatchedMeshBVH {\r\n  /**\r\n   * The target `BatchedMesh` object that the BVH is managing.\r\n   */\r\n  public target: BatchedMesh;\r\n  /**\r\n   * The BVH instance used to organize bounding volumes.\r\n   */\r\n  public bvh: BVH<{}, number>;\r\n  /**\r\n   * A map that stores the BVH nodes for each instance.\r\n   */\r\n  public nodesMap = new Map<number, BVHNode<{}, number>>();\r\n  /**\r\n   * Enables accurate frustum culling by checking intersections without applying margin to the bounding box.\r\n   */\r\n  public accurateCulling: boolean;\r\n  protected _margin: number;\r\n  protected _origin = new Float32Array(3);\r\n  protected _dir = new Float32Array(3);\r\n  protected _cameraPos = new Float32Array(3);\r\n  protected _boxArray = new Float32Array(6);\r\n\r\n  /**\r\n   * @param target The target `BatchedMesh`.\r\n   * @param margin The margin applied for bounding box calculations (default is 0).\r\n   * @param accurateCulling Flag to enable accurate frustum culling without considering margin (default is true).\r\n   */\r\n  constructor(target: BatchedMesh, coordinateSystem: CoordinateSystem, margin = 0, accurateCulling = true) {\r\n    this.target = target;\r\n    this.accurateCulling = accurateCulling;\r\n    this._margin = margin;\r\n\r\n    this.bvh = new BVH(new HybridBuilder(), coordinateSystem === 2000 ? WebGLCoordinateSystem : WebGPUCoordinateSystem); // TODO fix in BVH.js\r\n  }\r\n\r\n  /**\r\n   * Builds the BVH from the target mesh's instances using a top-down construction method.\r\n   * This approach is more efficient and accurate compared to incremental methods, which add one instance at a time.\r\n   */\r\n  public create(): void {\r\n    const count = this.target.instanceCount;\r\n    const instancesArrayCount = this.target._instanceInfo.length; // TODO this may change.. don't like it too much\r\n    const instancesInfo = this.target._instanceInfo;\r\n    const boxes: Float32Array[] = new Array(count); // test if single array and recreation inside node creation is faster due to memory location\r\n    const objects = new Uint32Array(count);\r\n    let index = 0;\r\n\r\n    this.clear();\r\n\r\n    for (let i = 0; i < instancesArrayCount; i++) {\r\n      if (!instancesInfo[i].active) continue;\r\n      boxes[index] = this.getBox(i, new Float32Array(6));\r\n      objects[index] = i;\r\n      index++;\r\n    }\r\n\r\n    this.bvh.createFromArray(objects as unknown as number[], boxes, (node) => {\r\n      this.nodesMap.set(node.object, node);\r\n    }, this._margin);\r\n  }\r\n\r\n  /**\r\n   * Inserts an instance into the BVH.\r\n   * @param id The id of the instance to insert.\r\n   */\r\n  public insert(id: number): void {\r\n    const node = this.bvh.insert(id, this.getBox(id, new Float32Array(6)), this._margin);\r\n    this.nodesMap.set(id, node);\r\n  }\r\n\r\n  /**\r\n   * Inserts a range of instances into the BVH.\r\n   * @param ids An array of ids to insert.\r\n   */\r\n  public insertRange(ids: number[]): void {\r\n    const count = ids.length;\r\n    const boxes: Float32Array[] = new Array(count);\r\n\r\n    for (let i = 0; i < count; i++) {\r\n      boxes[i] = this.getBox(ids[i], new Float32Array(6));\r\n    }\r\n\r\n    this.bvh.insertRange(ids, boxes, this._margin, (node) => {\r\n      this.nodesMap.set(node.object, node);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Moves an instance within the BVH.\r\n   * @param id The id of the instance to move.\r\n   */\r\n  public move(id: number): void {\r\n    const node = this.nodesMap.get(id);\r\n    if (!node) return;\r\n    this.getBox(id, node.box as Float32Array); // this also updates box\r\n    this.bvh.move(node, this._margin);\r\n  }\r\n\r\n  /**\r\n   * Deletes an instance from the BVH.\r\n   * @param id The id of the instance to delete.\r\n   */\r\n  public delete(id: number): void {\r\n    const node = this.nodesMap.get(id);\r\n    if (!node) return;\r\n    this.bvh.delete(node);\r\n    this.nodesMap.delete(id);\r\n  }\r\n\r\n  /**\r\n   * Clears the BVH.\r\n   */\r\n  public clear(): void {\r\n    this.bvh.clear();\r\n    this.nodesMap.clear();\r\n  }\r\n\r\n  /**\r\n   * Performs frustum culling to determine which instances are visible based on the provided projection matrix.\r\n   * @param projScreenMatrix The projection screen matrix for frustum culling.\r\n   * @param onFrustumIntersection Callback function invoked when an instance intersects the frustum.\r\n   */\r\n  public frustumCulling(projScreenMatrix: Matrix4, onFrustumIntersection: onFrustumIntersectionCallback<{}, number>): void {\r\n    if (this._margin > 0 && this.accurateCulling) {\r\n      this.bvh.frustumCulling(projScreenMatrix.elements, (node, frustum, mask) => {\r\n        if (frustum.isIntersectedMargin(node.box, mask, this._margin)) {\r\n          onFrustumIntersection(node);\r\n        }\r\n      });\r\n    } else {\r\n      this.bvh.frustumCulling(projScreenMatrix.elements, onFrustumIntersection);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Performs raycasting to check if a ray intersects any instances.\r\n   * @param raycaster The raycaster used for raycasting.\r\n   * @param onIntersection Callback function invoked when a ray intersects an instance.\r\n   */\r\n  public raycast(raycaster: Raycaster, onIntersection: onIntersectionRayCallback<number>): void {\r\n    const ray = raycaster.ray;\r\n    const origin = this._origin;\r\n    const dir = this._dir;\r\n\r\n    vec3ToArray(ray.origin, origin);\r\n    vec3ToArray(ray.direction, dir);\r\n\r\n    // TODO should we add margin check? maybe is not worth it\r\n    this.bvh.rayIntersections(dir, origin, onIntersection, raycaster.near, raycaster.far);\r\n  }\r\n\r\n  /**\r\n   * Checks if a given box intersects with any instance bounding box.\r\n   * @param target The target bounding box.\r\n   * @param onIntersection Callback function invoked when an intersection occurs.\r\n   * @returns `True` if there is an intersection, otherwise `false`.\r\n   */\r\n  public intersectBox(target: Box3, onIntersection: onIntersectionCallback<number>): boolean {\r\n    const array = this._boxArray;\r\n    box3ToArray(target, array);\r\n    return this.bvh.intersectsBox(array, onIntersection);\r\n  }\r\n\r\n  protected getBox(id: number, array: Float32Array): Float32Array {\r\n    const target = this.target;\r\n    const geometryId = target._instanceInfo[id].geometryIndex;\r\n    target.getBoundingBoxAt(geometryId, _box3).applyMatrix4(target.getMatrixAt(id, _matrix));\r\n    box3ToArray(_box3, array);\r\n    return array;\r\n  }\r\n}\r\n\r\nconst _box3 = new Box3();\r\nconst _matrix = new Matrix4();\r\n","export type MultiDrawRenderItem = { start: number; count: number; z: number; zSort?: number; index?: number };\r\n\r\n/**\r\n * A class that creates and manages a list of render items, used to determine the rendering order based on depth.\r\n * @internal\r\n */\r\nexport class MultiDrawRenderList {\r\n  public array: MultiDrawRenderItem[] = [];\r\n  protected pool: MultiDrawRenderItem[] = [];\r\n\r\n  public push(instanceId: number, depth: number, start: number, count: number): void {\r\n    const pool = this.pool;\r\n    const list = this.array;\r\n    const index = list.length;\r\n\r\n    if (index >= pool.length) {\r\n      pool.push({ start: null, count: null, z: null, zSort: null, index: null });\r\n    }\r\n\r\n    const item = pool[index];\r\n    item.index = instanceId;\r\n    item.start = start;\r\n    item.count = count;\r\n    item.z = depth;\r\n\r\n    list.push(item);\r\n  }\r\n\r\n  public reset(): void {\r\n    this.array.length = 0;\r\n  }\r\n}\r\n","import { BatchedMesh, CoordinateSystem } from 'three';\r\nimport { BatchedMeshBVH } from '../BatchedMeshBVH.js';\r\n\r\n/**\r\n * Parameters for configuring the BVH (Bounding Volume Hierarchy).\r\n */\r\nexport interface BVHParams {\r\n  /**\r\n   * Margin applied to accommodate animated or moving objects.\r\n   * Improves BVH update performance but slows down frustum culling and raycasting.\r\n   * For static objects, set to 0 to optimize culling and raycasting efficiency.\r\n   * @default 0\r\n   */\r\n  margin?: number;\r\n  /**\r\n   * Enables accurate frustum culling by checking intersections without applying margin to the bounding box.\r\n   * @default true\r\n   */\r\n  accurateCulling?: boolean;\r\n}\r\n\r\ndeclare module 'three' {\r\n  interface BatchedMesh {\r\n    /**\r\n     * BVH structure for optimized culling and intersection testing.\r\n     * It's possible to create the BVH using the `computeBVH` method. Once created it will be updated automatically.\r\n     */\r\n    bvh?: BatchedMeshBVH;\r\n    /**\r\n     * Creates and computes the BVH (Bounding Volume Hierarchy) for the instances.\r\n     * It's recommended to create it when all the instance matrices have been assigned.\r\n     * Once created it will be updated automatically.\r\n     * @param coordinateSystem The coordinate system (webgl or webgpu) in which the BVH is computed.\r\n     * @param config Optional configuration parameters object. See `BVHParams` for details.\r\n     */\r\n    computeBVH(coordinateSystem: CoordinateSystem, config?: BVHParams): void;\r\n  }\r\n}\r\n\r\nexport function computeBVH(this: BatchedMesh, coordinateSystem: CoordinateSystem, config: BVHParams = {}): void {\r\n  this.bvh = new BatchedMeshBVH(this, coordinateSystem, config.margin, config.accurateCulling);\r\n  this.bvh.create();\r\n}\r\n","import { BatchedMesh } from 'three';\r\nimport { radixSort, RadixSortOptions } from 'three/addons/utils/SortUtils.js';\r\nimport { MultiDrawRenderItem } from '../core/MultiDrawRenderList.js';\r\n\r\ntype radixSortCallback = (list: MultiDrawRenderItem[]) => void;\r\n\r\n/**\r\n * Creates a radix sort function specifically for sorting `BatchedMesh` instances.\r\n * The sorting is based on the `depth` property of each `MultiDrawRenderItem`.\r\n * This function dynamically adjusts for transparent materials by reversing the sort order if necessary.\r\n * @param target The `BatchedMesh` instance that contains the instances to be sorted.\r\n * @returns A radix sort function.\r\n * @reference https://github.com/mrdoob/three.js/blob/master/examples/webgl_mesh_batch.html#L291\r\n */\r\nexport function createRadixSort(target: BatchedMesh): radixSortCallback {\r\n  const options: RadixSortOptions<MultiDrawRenderItem> = {\r\n    get: (el) => el.zSort,\r\n    aux: new Array(target.maxInstanceCount),\r\n    reversed: null\r\n  };\r\n\r\n  return function sortFunction(list: MultiDrawRenderItem[]): void {\r\n    options.reversed = target.material.transparent;\r\n\r\n    if (target.maxInstanceCount > options.aux.length) {\r\n      options.aux.length = target.maxInstanceCount;\r\n    }\r\n\r\n    let minZ = Infinity;\r\n    let maxZ = -Infinity;\r\n\r\n    for (const { z } of list) {\r\n      if (z > maxZ) maxZ = z;\r\n      if (z < minZ) minZ = z;\r\n    }\r\n\r\n    const depthDelta = maxZ - minZ;\r\n    const factor = (2 ** 32 - 1) / depthDelta;\r\n\r\n    for (const item of list) {\r\n      item.zSort = (item.z - minZ) * factor;\r\n    }\r\n\r\n    radixSort(list, options);\r\n  };\r\n}\r\n\r\n/** @internal */\r\nexport function sortOpaque(a: MultiDrawRenderItem, b: MultiDrawRenderItem): number {\r\n  return a.z - b.z;\r\n}\r\n\r\n/** @internal */\r\nexport function sortTransparent(a: MultiDrawRenderItem, b: MultiDrawRenderItem): number {\r\n  return b.z - a.z;\r\n}\r\n","import { BVHNode } from 'bvh.js';\r\nimport { BatchedMesh, BufferGeometry, Camera, Frustum, Material, Matrix4, OrthographicCamera, PerspectiveCamera, Scene, Sphere, Vector3, WebGLRenderer } from 'three';\r\nimport { MultiDrawRenderItem, MultiDrawRenderList } from '../MultiDrawRenderList.js';\r\nimport { sortOpaque, sortTransparent } from '../../utils/SortingUtils.js';\r\n\r\n// TODO: fix LOD if no sorting and  no culling\r\n// TODO: viewSize can be calculate better\r\n\r\n/**\r\n * A custom sorting callback for render items.\r\n */\r\nexport type CustomSortCallback = (list: MultiDrawRenderItem[]) => void;\r\n\r\n/**\r\n * Callback invoked when an instance is within the frustum.\r\n * @param index The index of the instance.\r\n * @param camera The camera used for rendering.\r\n * @param cameraLOD The camera used for LOD calculations (provided only if LODs are initialized).\r\n * @param LODIndex The LOD level of the instance (provided only if LODs are initialized and `sortObjects` is false).\r\n * @returns True if the instance should be rendered, false otherwise.\r\n */\r\nexport type OnFrustumEnterCallback = (index: number, camera: Camera, cameraLOD?: Camera, LODIndex?: number) => boolean;\r\n\r\ndeclare module 'three' {\r\n  interface BatchedMesh {\r\n    /**\r\n     * Callback function called if an instance is inside the frustum.\r\n     */\r\n    onFrustumEnter?: OnFrustumEnterCallback;\r\n\r\n    /**\r\n     * Performs frustum culling and sorting.\r\n     * @param camera The main camera used for rendering.\r\n     * @param cameraLOD The camera used for LOD calculations (provided only if LODs are initialized).\r\n     */\r\n    frustumCulling(camera: Camera, cameraLOD?: Camera): void;\r\n    /**\r\n     * Updates the index array for indirect rendering.\r\n     */\r\n    updateIndexArray(): void;\r\n    /**\r\n     * Updates the render list based on the current visibility and sorting settings.\r\n     */\r\n    updateRenderList(): void;\r\n    /**\r\n     * Performs BVH frustum culling.\r\n     * @param camera The main camera used for rendering.\r\n     * @param cameraLOD The camera used for LOD calculations (provided only if LODs are initialized).\r\n     */\r\n    BVHCulling(camera: Camera, cameraLOD: Camera): void;\r\n    /**\r\n     * Performs linear frustum culling.\r\n     * @param camera The main camera used for rendering.\r\n     * @param cameraLOD The camera used for LOD calculations (provided only if LODs are initialized).\r\n     */\r\n    linearCulling(camera: Camera, cameraLOD: Camera): void;\r\n  }\r\n}\r\n\r\nconst _frustum = new Frustum();\r\nconst _renderList = new MultiDrawRenderList();\r\nconst _projScreenMatrix = new Matrix4();\r\nconst _invMatrixWorld = new Matrix4();\r\nconst _forward = new Vector3();\r\nconst _cameraPos = new Vector3();\r\nconst _cameraLODPos = new Vector3();\r\nconst _position = new Vector3();\r\nconst _sphere = new Sphere();\r\n\r\n// TODO move it\r\nexport function onBeforeRender(this: BatchedMesh, renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry, material: Material, group: any): void {\r\n  // TODO check if nothing changed\r\n  this.frustumCulling(camera);\r\n  this.uniformsTexture?.update(renderer);\r\n}\r\n\r\nexport function frustumCulling(this: BatchedMesh, camera: Camera, cameraLOD = camera): void {\r\n  if (!this._visibilityChanged && !this.perObjectFrustumCulled && !this.sortObjects) {\r\n    return;\r\n  }\r\n\r\n  this._indirectTexture.needsUpdate = true;\r\n  this._visibilityChanged = false;\r\n\r\n  const sortObjects = this.sortObjects;\r\n  const perObjectFrustumCulled = this.perObjectFrustumCulled;\r\n\r\n  if (!perObjectFrustumCulled && !sortObjects) {\r\n    this.updateIndexArray();\r\n    return;\r\n  }\r\n\r\n  _invMatrixWorld.copy(this.matrixWorld).invert();\r\n  _cameraPos.setFromMatrixPosition(camera.matrixWorld).applyMatrix4(_invMatrixWorld);\r\n  _cameraLODPos.setFromMatrixPosition(cameraLOD.matrixWorld).applyMatrix4(_invMatrixWorld);\r\n  _forward.set(0, 0, -1).transformDirection(camera.matrixWorld).transformDirection(_invMatrixWorld);\r\n\r\n  if (!perObjectFrustumCulled) {\r\n    this.updateRenderList();\r\n  } else {\r\n    _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse).multiply(this.matrixWorld);\r\n\r\n    if (this.bvh) this.BVHCulling(camera, cameraLOD);\r\n    else this.linearCulling(camera, cameraLOD);\r\n  }\r\n\r\n  if (sortObjects) {\r\n    const index = this.geometry.getIndex();\r\n    const bytesPerElement = index === null ? 1 : index.array.BYTES_PER_ELEMENT;\r\n    const multiDrawStarts = this._multiDrawStarts;\r\n    const multiDrawCounts = this._multiDrawCounts;\r\n    const indirectArray = this._indirectTexture.image.data as unknown as number[];\r\n    const customSort = this.customSort as unknown as CustomSortCallback;\r\n\r\n    if (customSort === null) {\r\n      _renderList.array.sort(!this.material.transparent ? sortOpaque : sortTransparent);\r\n    } else {\r\n      customSort(_renderList.array); // TODO fix and remove second useless parameter... make a PR on main repo\r\n    }\r\n\r\n    const list = _renderList.array;\r\n    const count = list.length;\r\n    for (let i = 0; i < count; i++) {\r\n      const item = list[i];\r\n      multiDrawStarts[i] = item.start * bytesPerElement; // TODO multiply bytesPerElement in the renderList?\r\n      multiDrawCounts[i] = item.count;\r\n      indirectArray[i] = item.index;\r\n    }\r\n\r\n    _renderList.reset();\r\n  }\r\n}\r\n\r\nexport function updateIndexArray(this: BatchedMesh): void {\r\n  if (!this._visibilityChanged) return;\r\n\r\n  const index = this.geometry.getIndex();\r\n  const bytesPerElement = index === null ? 1 : index.array.BYTES_PER_ELEMENT;\r\n  const instanceInfo = this._instanceInfo;\r\n  const geometryInfoList = this._geometryInfo;\r\n  const multiDrawStarts = this._multiDrawStarts;\r\n  const multiDrawCounts = this._multiDrawCounts;\r\n  const indirectArray = this._indirectTexture.image.data as unknown as number[];\r\n  let count = 0;\r\n\r\n  for (let i = 0, l = instanceInfo.length; i < l; i++) {\r\n    const instance = instanceInfo[i];\r\n    if (instance.visible && instance.active) {\r\n      const geometryId = instance.geometryIndex;\r\n      const geometryInfo = geometryInfoList[geometryId];\r\n\r\n      multiDrawStarts[count] = geometryInfo.start * bytesPerElement;\r\n      multiDrawCounts[count] = geometryInfo.count;\r\n      indirectArray[count] = i;\r\n      count++;\r\n    }\r\n  }\r\n\r\n  this._multiDrawCount = count;\r\n}\r\n\r\nexport function updateRenderList(this: BatchedMesh): void {\r\n  const instanceInfo = this._instanceInfo;\r\n  const geometryInfoList = this._geometryInfo;\r\n\r\n  for (let i = 0, l = instanceInfo.length; i < l; i++) {\r\n    const instance = instanceInfo[i];\r\n    if (instance.visible && instance.active) {\r\n      const geometryId = instance.geometryIndex;\r\n      const geometryInfo = geometryInfoList[geometryId];\r\n      const depth = this.getPositionAt(i).sub(_cameraPos).dot(_forward); // getPosition instead of _sphere.center\r\n      _renderList.push(i, depth, geometryInfo.start, geometryInfo.count);\r\n    }\r\n  }\r\n\r\n  this._multiDrawCount = _renderList.array.length;\r\n}\r\n\r\nexport function BVHCulling(this: BatchedMesh, camera: Camera, cameraLOD: Camera): void {\r\n  const index = this.geometry.getIndex();\r\n  const bytesPerElement = index === null ? 1 : index.array.BYTES_PER_ELEMENT;\r\n  const instanceInfo = this._instanceInfo;\r\n  const geometryInfoList = this._geometryInfo;\r\n  const sortObjects = this.sortObjects;\r\n  const multiDrawStarts = this._multiDrawStarts;\r\n  const multiDrawCounts = this._multiDrawCounts;\r\n  const indirectArray = this._indirectTexture.image.data as unknown as number[];\r\n  const onFrustumEnter = this.onFrustumEnter;\r\n  let instancesCount = 0;\r\n\r\n  const orthographicCamera = camera as OrthographicCamera;\r\n  const viewSize = (orthographicCamera.top - orthographicCamera.bottom) / orthographicCamera.zoom;\r\n  const perspectiveCamera = camera as PerspectiveCamera;\r\n  const invProj = (Math.tan(perspectiveCamera.fov * 0.5 * (Math.PI / 180))) ** 2;\r\n  const useDistanceForLOD = this.useDistanceForLOD;\r\n  const isPerspectiveCamera = perspectiveCamera.isPerspectiveCamera;\r\n\r\n  this.bvh.frustumCulling(_projScreenMatrix, (node: BVHNode<{}, number>) => {\r\n    const index = node.object;\r\n    const instance = instanceInfo[index];\r\n\r\n    // we don't check if active because we remove inactive instances from BVH\r\n    if (!instance.visible) return;\r\n\r\n    const geometryId = instance.geometryIndex;\r\n    const geometryInfo = geometryInfoList[geometryId];\r\n    const LOD = geometryInfo.LOD;\r\n    let start: number;\r\n    let count: number;\r\n\r\n    if (LOD) {\r\n      _sphere.radius = geometryInfo.boundingSphere.radius;\r\n\r\n      let metric: number;\r\n      if (isPerspectiveCamera) {\r\n        const distance = this.getPositionAt(index).distanceToSquared(_cameraLODPos);\r\n        metric = getLODMetricPerspective(useDistanceForLOD, _sphere, invProj, distance);\r\n      } else {\r\n        metric = getLODMetricOrthographic(useDistanceForLOD, _sphere, viewSize);\r\n      }\r\n      const LODIndex = this.getLODIndex(LOD, metric, isPerspectiveCamera);\r\n\r\n      if (onFrustumEnter && !onFrustumEnter(index, camera, cameraLOD, LODIndex)) return;\r\n      start = LOD[LODIndex].start;\r\n      count = LOD[LODIndex].count;\r\n    } else {\r\n      if (onFrustumEnter && !onFrustumEnter(index, camera)) return;\r\n      start = geometryInfo.start;\r\n      count = geometryInfo.count;\r\n    }\r\n\r\n    // TODO don't reuse getPositionAt for sort\r\n    // TODO LOD optimized if bvh and sort?\r\n\r\n    if (sortObjects) {\r\n      const depth = this.getPositionAt(index).sub(_cameraPos).dot(_forward);\r\n      _renderList.push(index, depth, start, count);\r\n    } else {\r\n      multiDrawStarts[instancesCount] = start * bytesPerElement;\r\n      multiDrawCounts[instancesCount] = count;\r\n      indirectArray[instancesCount] = index;\r\n      instancesCount++;\r\n    }\r\n  });\r\n\r\n  this._multiDrawCount = sortObjects ? _renderList.array.length : instancesCount;\r\n}\r\n\r\nfunction getLODMetricPerspective(useDistanceForLOD: boolean, sphere: Sphere, invProj: number, distance: number): number {\r\n  return useDistanceForLOD ? distance : ((sphere.radius ** 2) / (distance * invProj));\r\n}\r\n\r\nfunction getLODMetricOrthographic(useDistanceForLOD: boolean, sphere: Sphere, viewHeight: number): number {\r\n  // TODO refactor\r\n  if (useDistanceForLOD) throw new Error('BatchedMesh: useDistanceForLOD cannot be used with orthographic camera.');\r\n  return sphere.radius * 2 / viewHeight;\r\n}\r\n\r\nexport function linearCulling(this: BatchedMesh, camera: Camera, cameraLOD: Camera): void {\r\n  const index = this.geometry.getIndex();\r\n  const bytesPerElement = index === null ? 1 : index.array.BYTES_PER_ELEMENT;\r\n  const instanceInfo = this._instanceInfo;\r\n  const geometryInfoList = this._geometryInfo;\r\n  const sortObjects = this.sortObjects;\r\n  const multiDrawStarts = this._multiDrawStarts;\r\n  const multiDrawCounts = this._multiDrawCounts;\r\n  const indirectArray = this._indirectTexture.image.data as unknown as number[];\r\n  const onFrustumEnter = this.onFrustumEnter;\r\n  let instancesCount = 0;\r\n\r\n  _frustum.setFromProjectionMatrix(_projScreenMatrix);\r\n\r\n  const orthographicCamera = camera as OrthographicCamera;\r\n  const viewSize = (orthographicCamera.top - orthographicCamera.bottom) / orthographicCamera.zoom;\r\n  const perspectiveCamera = camera as PerspectiveCamera;\r\n  const invProj = (Math.tan(perspectiveCamera.fov * 0.5 * (Math.PI / 180))) ** 2;\r\n  const useDistanceForLOD = this.useDistanceForLOD;\r\n  const isPerspectiveCamera = perspectiveCamera.isPerspectiveCamera;\r\n\r\n  for (let i = 0, l = instanceInfo.length; i < l; i++) {\r\n    const instance = instanceInfo[i];\r\n    if (!instance.visible || !instance.active) continue;\r\n\r\n    const geometryId = instance.geometryIndex;\r\n    const geometryInfo = geometryInfoList[geometryId];\r\n    const LOD = geometryInfo.LOD;\r\n    let start: number;\r\n    let count: number;\r\n\r\n    const bSphere = geometryInfo.boundingSphere;\r\n    const radius = bSphere.radius;\r\n    const center = bSphere.center;\r\n    const geometryCentered = center.x === 0 && center.y === 0 && center.z === 0; // TODO add to geometryInfo?\r\n\r\n    if (geometryCentered) {\r\n      const maxScale = this.getPositionAndMaxScaleOnAxisAt(i, _sphere.center);\r\n      _sphere.radius = radius * maxScale;\r\n    } else {\r\n      this.applyMatrixAtToSphere(i, _sphere, center, radius);\r\n    }\r\n\r\n    if (!_frustum.intersectsSphere(_sphere)) continue;\r\n\r\n    if (LOD) {\r\n      let metric: number;\r\n      if (isPerspectiveCamera) {\r\n        const distance = _sphere.center.distanceToSquared(_cameraLODPos);\r\n        metric = getLODMetricPerspective(useDistanceForLOD, _sphere, invProj, distance);\r\n      } else {\r\n        metric = getLODMetricOrthographic(useDistanceForLOD, _sphere, viewSize);\r\n      }\r\n      const LODIndex = this.getLODIndex(LOD, metric, isPerspectiveCamera);\r\n\r\n      if (onFrustumEnter && !onFrustumEnter(i, camera, cameraLOD, LODIndex)) continue;\r\n      start = LOD[LODIndex].start;\r\n      count = LOD[LODIndex].count;\r\n    } else {\r\n      if (onFrustumEnter && !onFrustumEnter(i, camera)) continue;\r\n      start = geometryInfo.start;\r\n      count = geometryInfo.count;\r\n    }\r\n\r\n    // TODO LOD optimized if sort?\r\n\r\n    if (sortObjects) {\r\n      const depth = _position.subVectors(_sphere.center, _cameraPos).dot(_forward);\r\n      _renderList.push(i, depth, start, count);\r\n    } else {\r\n      multiDrawStarts[instancesCount] = start * bytesPerElement;\r\n      multiDrawCounts[instancesCount] = count;\r\n      indirectArray[instancesCount] = i;\r\n      instancesCount++;\r\n    }\r\n  }\r\n\r\n  this._multiDrawCount = sortObjects ? _renderList.array.length : instancesCount;\r\n}\r\n","import { BatchedMesh, Sphere, Vector3 } from 'three';\r\n\r\ndeclare module 'three' {\r\n  interface BatchedMesh {\r\n    /**\r\n     * Retrieves the position of a specific instance.\r\n     * @param index The index of the instance.\r\n     * @param target Optional `Vector3` to store the result.\r\n     * @returns The position of the instance as a `Vector3`.\r\n     */\r\n    getPositionAt(index: number, target?: Vector3): Vector3;\r\n    /**\r\n     * Retrieves the position and maximum scale on any axis of a specific instance.\r\n     * @param index The index of the instance.\r\n     * @param position Optional `Vector3` to store the position result.\r\n     * @returns The maximum scale on any axis.\r\n     */\r\n    getPositionAndMaxScaleOnAxisAt(index: number, position: Vector3): number;\r\n    /**\r\n     * Applies the transformation matrix of a specific instance to a sphere.\r\n     * @param index The index of the instance.\r\n     * @param sphere The sphere to transform.\r\n     * @param center TODO\r\n     * @param radius TODO\r\n     */\r\n    applyMatrixAtToSphere(index: number, sphere: Sphere, center: Vector3, radius: number): void;\r\n  }\r\n}\r\n\r\nconst _position = new Vector3();\r\n\r\nexport function getPositionAt(this: BatchedMesh, index: number, target = _position): Vector3 {\r\n  const offset = index * 16;\r\n  const array = this._matricesTexture.image.data as unknown as number[];\r\n\r\n  target.x = array[offset + 12];\r\n  target.y = array[offset + 13];\r\n  target.z = array[offset + 14];\r\n\r\n  return target;\r\n}\r\n\r\nexport function getPositionAndMaxScaleOnAxisAt(this: BatchedMesh, index: number, position: Vector3): number {\r\n  const offset = index * 16;\r\n  const array = this._matricesTexture.image.data as unknown as number[];\r\n\r\n  const te0 = array[offset + 0];\r\n  const te1 = array[offset + 1];\r\n  const te2 = array[offset + 2];\r\n  const scaleXSq = te0 * te0 + te1 * te1 + te2 * te2;\r\n\r\n  const te4 = array[offset + 4];\r\n  const te5 = array[offset + 5];\r\n  const te6 = array[offset + 6];\r\n  const scaleYSq = te4 * te4 + te5 * te5 + te6 * te6;\r\n\r\n  const te8 = array[offset + 8];\r\n  const te9 = array[offset + 9];\r\n  const te10 = array[offset + 10];\r\n  const scaleZSq = te8 * te8 + te9 * te9 + te10 * te10;\r\n\r\n  position.x = array[offset + 12];\r\n  position.y = array[offset + 13];\r\n  position.z = array[offset + 14];\r\n\r\n  return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq));\r\n}\r\n\r\nexport function applyMatrixAtToSphere(this: BatchedMesh, index: number, sphere: Sphere, center: Vector3, radius: number): void {\r\n  const offset = index * 16;\r\n  const array = this._matricesTexture.image.data as unknown as number[];\r\n\r\n  const te0 = array[offset + 0];\r\n  const te1 = array[offset + 1];\r\n  const te2 = array[offset + 2];\r\n  const te3 = array[offset + 3];\r\n  const te4 = array[offset + 4];\r\n  const te5 = array[offset + 5];\r\n  const te6 = array[offset + 6];\r\n  const te7 = array[offset + 7];\r\n  const te8 = array[offset + 8];\r\n  const te9 = array[offset + 9];\r\n  const te10 = array[offset + 10];\r\n  const te11 = array[offset + 11];\r\n  const te12 = array[offset + 12];\r\n  const te13 = array[offset + 13];\r\n  const te14 = array[offset + 14];\r\n  const te15 = array[offset + 15];\r\n\r\n  const position = sphere.center;\r\n  const x = center.x;\r\n  const y = center.y;\r\n  const z = center.z;\r\n  const w = 1 / (te3 * x + te7 * y + te11 * z + te15);\r\n\r\n  position.x = (te0 * x + te4 * y + te8 * z + te12) * w;\r\n  position.y = (te1 * x + te5 * y + te9 * z + te13) * w;\r\n  position.z = (te2 * x + te6 * y + te10 * z + te14) * w;\r\n\r\n  const scaleXSq = te0 * te0 + te1 * te1 + te2 * te2;\r\n  const scaleYSq = te4 * te4 + te5 * te5 + te6 * te6;\r\n  const scaleZSq = te8 * te8 + te9 * te9 + te10 * te10;\r\n\r\n  sphere.radius = radius * Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq));\r\n}\r\n","import { BatchedMesh, BufferGeometry, TypedArray } from 'three';\r\n\r\n// TODO: add optional distance and first load function like InstancedMesh2\r\n// TODO: improve and fix comments\r\n// TODO: should we use an internal different metood instead of adding a flag in getLODIndex?\r\n// TODO: if we use distance for LOD, should we update the LOD0 metric infinity to 0\r\n\r\nexport type LODInfo = { start: number; count: number; metric: number; metricSquared: number };\r\n\r\ndeclare module 'three' {\r\n  interface BatchedMesh {\r\n    /**\r\n     * If `true`, LOD uses camera distance; otherwise it uses screen size.\r\n     * @default undefined\r\n     */\r\n    useDistanceForLOD?: boolean;\r\n    /**\r\n     * Adds a Level of Detail (LOD) geometry to the BatchedMesh.\r\n     * @param geometryId The ID of the geometry to which the LOD is being added.\r\n     * @param geometryOrIndex The BufferGeometry to be added as LOD or the index array.\r\n     * @param metric The screen-space metric (e.g., fraction of screen height) at which this LOD should be used.\r\n     */\r\n    addGeometryLOD(geometryId: number, geometryOrIndex: BufferGeometry | TypedArray, metric: number): void;\r\n    /**\r\n     * Retrieves the LOD index for a given screen-space metric.\r\n     * @param LOD The array of LOD information.\r\n     * @param metric The calculated screen-space metric for the object.\r\n     * @param useDistSquared Whether to use the squared distance for LOD calculations.\r\n     * @returns The index of the appropriate LOD\r\n     */\r\n    getLODIndex(LOD: LODInfo[], metric: number, useDistSquared?: boolean): number;\r\n  }\r\n}\r\n\r\nexport function addGeometryLOD(this: BatchedMesh, geometryId: number, geoOrIndex: BufferGeometry | TypedArray, metric: number): void {\r\n  const geometryInfo = this._geometryInfo[geometryId];\r\n  const srcIndexArray = (geoOrIndex as BufferGeometry).isBufferGeometry ? (geoOrIndex as BufferGeometry).index.array : geoOrIndex as TypedArray;\r\n  const metricSquared = metric ** 2;\r\n\r\n  geometryInfo.LOD ??= [{ start: geometryInfo.start, count: geometryInfo.count, metric: Infinity, metricSquared: Infinity }];\r\n\r\n  const LOD = geometryInfo.LOD;\r\n  const lastLOD = LOD[LOD.length - 1];\r\n  const start = lastLOD.start + lastLOD.count;\r\n  const count = srcIndexArray.length;\r\n\r\n  if ((start - geometryInfo.start) + count > geometryInfo.reservedIndexCount) {\r\n    throw new Error('BatchedMesh LOD: Reserved space request exceeds the maximum buffer size.');\r\n  }\r\n\r\n  LOD.push({ start, count, metric, metricSquared });\r\n\r\n  const dstIndex = this.geometry.getIndex();\r\n  const dstIndexArray = dstIndex.array;\r\n  const vertexStart = geometryInfo.vertexStart;\r\n\r\n  for (let i = 0; i < count; i++) {\r\n    dstIndexArray[start + i] = srcIndexArray[i] + vertexStart;\r\n  }\r\n\r\n  dstIndex.needsUpdate = true;\r\n}\r\n\r\nexport function getLODIndex(this: BatchedMesh, LODs: LODInfo[], metric: number, useDistSquared = false): number {\r\n  const metricKey: keyof LODInfo = useDistSquared ? 'metricSquared' : 'metric';\r\n\r\n  if (this.useDistanceForLOD) {\r\n    for (let i = LODs.length - 1; i > 0; i--) {\r\n      const level = LODs[i];\r\n      const distance = level[metricKey];\r\n      if (metric >= distance) return i;\r\n    }\r\n\r\n    return 0;\r\n  }\r\n\r\n  for (let i = LODs.length - 1; i > 0; i--) {\r\n    const level = LODs[i];\r\n    const screenSize = level[metricKey];\r\n    if (metric <= screenSize) return i;\r\n  }\r\n\r\n  return 0;\r\n}\r\n","import { BatchedMesh, Box3, Intersection, Matrix4, Mesh, Ray, Raycaster, Sphere, Vector3 } from 'three';\r\nimport { } from 'three-mesh-bvh'; // include only types\r\n\r\ndeclare module 'three' {\r\n  interface BatchedMesh {\r\n    checkInstanceIntersection(raycaster: Raycaster, objectIndex: number, result: Intersection[]): void;\r\n  }\r\n}\r\n\r\nconst _intersections: Intersection[] = [];\r\nconst _mesh = new Mesh();\r\nconst _ray = new Ray();\r\nconst _direction = new Vector3();\r\nconst _worldScale = new Vector3();\r\nconst _invMatrixWorld = new Matrix4();\r\n\r\nexport function raycast(this: BatchedMesh, raycaster: Raycaster, result: Intersection[]): void {\r\n  if (!this.material || this.instanceCount === 0) return;\r\n\r\n  _mesh.geometry = this.geometry;\r\n  _mesh.material = this.material;\r\n\r\n  _mesh.geometry.boundingBox ??= new Box3();\r\n  _mesh.geometry.boundingSphere ??= new Sphere();\r\n\r\n  const originalRay = raycaster.ray;\r\n  const originalNear = raycaster.near;\r\n  const originalFar = raycaster.far;\r\n\r\n  _invMatrixWorld.copy(this.matrixWorld).invert();\r\n\r\n  _worldScale.setFromMatrixScale(this.matrixWorld);\r\n  _direction.copy(raycaster.ray.direction).multiply(_worldScale);\r\n  const scaleFactor = _direction.length();\r\n\r\n  raycaster.ray = _ray.copy(raycaster.ray).applyMatrix4(_invMatrixWorld);\r\n  raycaster.near /= scaleFactor;\r\n  raycaster.far /= scaleFactor;\r\n\r\n  if (this.bvh) {\r\n    this.bvh.raycast(raycaster, (instanceId) => this.checkInstanceIntersection(raycaster, instanceId, result));\r\n  } else {\r\n    if (this.boundingSphere === null) this.computeBoundingSphere();\r\n\r\n    if (raycaster.ray.intersectsSphere(this.boundingSphere)) {\r\n      for (let i = 0, l = this._instanceInfo.length; i < l; i++) {\r\n        this.checkInstanceIntersection(raycaster, i, result);\r\n      }\r\n    }\r\n  }\r\n\r\n  raycaster.ray = originalRay;\r\n  raycaster.near = originalNear;\r\n  raycaster.far = originalFar;\r\n}\r\n\r\nexport function checkInstanceIntersection(this: BatchedMesh, raycaster: Raycaster, instanceId: number, result: Intersection[]): void {\r\n  const info = this._instanceInfo[instanceId];\r\n  if (!info.active || !info.visible) return;\r\n\r\n  const geometryId = info.geometryIndex;\r\n  const geometryInfo = this._geometryInfo[geometryId];\r\n\r\n  this.getMatrixAt(instanceId, _mesh.matrixWorld);\r\n\r\n  _mesh.geometry.boundsTree = this.boundsTrees ? this.boundsTrees[geometryId] : undefined; // three-mesh-bvh compatibility\r\n\r\n  if (!_mesh.geometry.boundsTree) {\r\n    this.getBoundingBoxAt(geometryId, _mesh.geometry.boundingBox);\r\n    this.getBoundingSphereAt(geometryId, _mesh.geometry.boundingSphere);\r\n    _mesh.geometry.setDrawRange(geometryInfo.start, geometryInfo.count);\r\n  }\r\n\r\n  _mesh.raycast(raycaster, _intersections);\r\n\r\n  for (const intersect of _intersections) {\r\n    intersect.batchId = instanceId;\r\n    intersect.object = this;\r\n    result.push(intersect);\r\n  }\r\n\r\n  _intersections.length = 0;\r\n}\r\n","import { BatchedMesh } from 'three';\r\nimport { computeBVH } from '../core/feature/ComputeBVH.js';\r\nimport { BVHCulling, frustumCulling, linearCulling, onBeforeRender, updateIndexArray, updateRenderList } from '../core/feature/FrustumCulling.js';\r\nimport { applyMatrixAtToSphere, getPositionAndMaxScaleOnAxisAt, getPositionAt } from '../core/feature/GetPositionAt.js';\r\nimport { addGeometryLOD, getLODIndex } from '../core/feature/LOD.js';\r\nimport { checkInstanceIntersection, raycast } from '../core/feature/Raycasting.js';\r\n\r\n/**\r\n * @internal\r\n * Enhances the BatchedMesh prototype with additional methods.\r\n */\r\nexport function extendBatchedMeshPrototypeCommon(): void {\r\n  BatchedMesh.prototype.computeBVH = computeBVH;\r\n\r\n  BatchedMesh.prototype.onBeforeRender = onBeforeRender;\r\n  BatchedMesh.prototype.frustumCulling = frustumCulling;\r\n  BatchedMesh.prototype.updateIndexArray = updateIndexArray;\r\n  BatchedMesh.prototype.updateRenderList = updateRenderList;\r\n  BatchedMesh.prototype.BVHCulling = BVHCulling;\r\n  BatchedMesh.prototype.linearCulling = linearCulling;\r\n\r\n  BatchedMesh.prototype.getPositionAt = getPositionAt;\r\n  BatchedMesh.prototype.getPositionAndMaxScaleOnAxisAt = getPositionAndMaxScaleOnAxisAt;\r\n  BatchedMesh.prototype.applyMatrixAtToSphere = applyMatrixAtToSphere;\r\n\r\n  BatchedMesh.prototype.addGeometryLOD = addGeometryLOD;\r\n  BatchedMesh.prototype.getLODIndex = getLODIndex;\r\n\r\n  BatchedMesh.prototype.raycast = raycast;\r\n  BatchedMesh.prototype.checkInstanceIntersection = checkInstanceIntersection;\r\n}\r\n","import { extendBatchedMeshPrototypeCommon } from './ExtendBatchedMeshPrototype.common.js';\r\n\r\n/**\r\n * Enhances the BatchedMesh prototype with additional methods.\r\n */\r\nexport function extendBatchedMeshPrototype(): void {\r\n  extendBatchedMeshPrototypeCommon();\r\n}\r\n","import { BatchedMesh, WebGLProgramParametersWithUniforms, WebGLRenderer } from 'three';\r\n\r\nexport function patchBatchedMeshMaterial(batchedMesh: BatchedMesh): void {\r\n  const material = batchedMesh.material;\r\n  const onBeforeCompileBase = material.onBeforeCompile.bind(material);\r\n\r\n  // TODO edit also the material compile cache key?\r\n\r\n  material.onBeforeCompile = (shader: WebGLProgramParametersWithUniforms, renderer: WebGLRenderer) => {\r\n    if (batchedMesh.uniformsTexture) {\r\n      shader.uniforms.uniformsTexture = { value: batchedMesh.uniformsTexture };\r\n      const { vertex, fragment } = batchedMesh.uniformsTexture.getUniformsGLSL('uniformsTexture', 'batchIndex', 'float');\r\n      shader.vertexShader = shader.vertexShader.replace('void main() {', vertex);\r\n      shader.fragmentShader = shader.fragmentShader.replace('void main() {', fragment);\r\n\r\n      shader.vertexShader = shader.vertexShader.replace('void main() {', 'void main() { float batchIndex = getIndirectIndex( gl_DrawID );');\r\n    }\r\n\r\n    onBeforeCompileBase(shader, renderer);\r\n  };\r\n}\r\n","import { BufferGeometry } from 'three';\r\n\r\nexport type VertexIndexCount = { vertexCount: number; indexCount: number };\r\nexport type VertexIndexLODCount = { vertexCount: number; indexCount: number; LODIndexCount: number[] };\r\n\r\nexport function getBatchedMeshCount(geometries: BufferGeometry[]): VertexIndexCount {\r\n  let vertexCount = 0;\r\n  let indexCount = 0;\r\n\r\n  for (const geometry of geometries) {\r\n    vertexCount += geometry.attributes.position.count;\r\n    indexCount += geometry.index.count;\r\n  }\r\n\r\n  return { vertexCount, indexCount };\r\n}\r\n\r\nexport function getBatchedMeshLODCount(geometryLOD: BufferGeometry[][]): VertexIndexLODCount {\r\n  const LODIndexCount: number[] = [];\r\n  let vertexCount = 0;\r\n  let indexCount = 0;\r\n\r\n  for (const geometries of geometryLOD) {\r\n    let sum = 0;\r\n\r\n    for (const geometry of geometries) {\r\n      const count = geometry.index.count;\r\n      indexCount += count;\r\n      sum += count;\r\n      vertexCount += geometry.attributes.position.count;\r\n    }\r\n\r\n    LODIndexCount.push(sum);\r\n  }\r\n\r\n  return { vertexCount, indexCount, LODIndexCount };\r\n}\r\n"],"names":["BatchedMeshBVH","target","coordinateSystem","margin","accurateCulling","BVH","HybridBuilder","WebGLCoordinateSystem","WebGPUCoordinateSystem","count","instancesArrayCount","instancesInfo","boxes","objects","index","i","node","id","ids","projScreenMatrix","onFrustumIntersection","frustum","mask","raycaster","onIntersection","ray","origin","dir","vec3ToArray","array","box3ToArray","geometryId","_box3","_matrix","Box3","Matrix4","MultiDrawRenderList","instanceId","depth","start","pool","list","item","computeBVH","config","createRadixSort","options","el","minZ","maxZ","z","depthDelta","factor","radixSort","sortOpaque","a","b","sortTransparent","_frustum","Frustum","_renderList","_projScreenMatrix","_invMatrixWorld","_forward","Vector3","_cameraPos","_cameraLODPos","_position","_sphere","Sphere","onBeforeRender","renderer","scene","camera","geometry","material","group","_a","frustumCulling","cameraLOD","sortObjects","perObjectFrustumCulled","bytesPerElement","multiDrawStarts","multiDrawCounts","indirectArray","customSort","updateIndexArray","instanceInfo","geometryInfoList","l","instance","geometryInfo","updateRenderList","BVHCulling","onFrustumEnter","instancesCount","orthographicCamera","viewSize","perspectiveCamera","invProj","useDistanceForLOD","isPerspectiveCamera","LOD","metric","distance","getLODMetricPerspective","getLODMetricOrthographic","LODIndex","sphere","viewHeight","linearCulling","bSphere","radius","center","maxScale","getPositionAt","offset","getPositionAndMaxScaleOnAxisAt","position","te0","te1","te2","scaleXSq","te4","te5","te6","scaleYSq","te8","te9","te10","scaleZSq","applyMatrixAtToSphere","te3","te7","te11","te12","te13","te14","te15","x","w","addGeometryLOD","geoOrIndex","srcIndexArray","metricSquared","lastLOD","dstIndex","dstIndexArray","vertexStart","getLODIndex","LODs","useDistSquared","metricKey","screenSize","_intersections","_mesh","Mesh","_ray","Ray","_direction","_worldScale","raycast","result","_b","originalRay","originalNear","originalFar","scaleFactor","checkInstanceIntersection","info","intersect","extendBatchedMeshPrototypeCommon","BatchedMesh","extendBatchedMeshPrototype","patchBatchedMeshMaterial","batchedMesh","onBeforeCompileBase","shader","vertex","fragment","getBatchedMeshCount","geometries","vertexCount","indexCount","getBatchedMeshLODCount","geometryLOD","LODIndexCount","sum"],"mappings":"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"}