1 |
- {"ast":null,"code":"import { Epsilon } from \"../Maths/math.constants.js\";\nimport { Matrix, TmpVectors, Vector3 } from \"../Maths/math.vector.js\";\nimport { BuildArray } from \"../Misc/arrayTools.js\";\nimport { IntersectionInfo } from \"../Collisions/intersectionInfo.js\";\nimport { PickingInfo } from \"../Collisions/pickingInfo.js\";\nimport { EngineStore } from \"../Engines/engineStore.js\";\nimport { _ImportHelper } from \"../import.helper.js\";\n/**\n * Use this object to customize mesh picking behavior\n */\nexport const PickingCustomization = {\n internalPickerForMesh: undefined\n};\n/**\n * Class representing a ray with position and direction\n */\nexport class Ray {\n /**\n * Creates a new ray\n * @param origin origin point\n * @param direction direction\n * @param length length of the ray\n * @param epsilon The epsilon value to use when calculating the ray/triangle intersection (default: 0)\n */\n constructor( /** origin point */\n origin, /** direction */\n direction, /** [Number.MAX_VALUE] length of the ray */\n length = Number.MAX_VALUE, /** [Epsilon] The epsilon value to use when calculating the ray/triangle intersection (default: Epsilon from math constants) */\n epsilon = Epsilon) {\n this.origin = origin;\n this.direction = direction;\n this.length = length;\n this.epsilon = epsilon;\n }\n // Methods\n /**\n * Clone the current ray\n * @returns a new ray\n */\n clone() {\n return new Ray(this.origin.clone(), this.direction.clone(), this.length);\n }\n /**\n * Checks if the ray intersects a box\n * This does not account for the ray length by design to improve perfs.\n * @param minimum bound of the box\n * @param maximum bound of the box\n * @param intersectionTreshold extra extend to be added to the box in all direction\n * @returns if the box was hit\n */\n intersectsBoxMinMax(minimum, maximum, intersectionTreshold = 0) {\n const newMinimum = Ray._TmpVector3[0].copyFromFloats(minimum.x - intersectionTreshold, minimum.y - intersectionTreshold, minimum.z - intersectionTreshold);\n const newMaximum = Ray._TmpVector3[1].copyFromFloats(maximum.x + intersectionTreshold, maximum.y + intersectionTreshold, maximum.z + intersectionTreshold);\n let d = 0.0;\n let maxValue = Number.MAX_VALUE;\n let inv;\n let min;\n let max;\n let temp;\n if (Math.abs(this.direction.x) < 0.0000001) {\n if (this.origin.x < newMinimum.x || this.origin.x > newMaximum.x) {\n return false;\n }\n } else {\n inv = 1.0 / this.direction.x;\n min = (newMinimum.x - this.origin.x) * inv;\n max = (newMaximum.x - this.origin.x) * inv;\n if (max === -Infinity) {\n max = Infinity;\n }\n if (min > max) {\n temp = min;\n min = max;\n max = temp;\n }\n d = Math.max(min, d);\n maxValue = Math.min(max, maxValue);\n if (d > maxValue) {\n return false;\n }\n }\n if (Math.abs(this.direction.y) < 0.0000001) {\n if (this.origin.y < newMinimum.y || this.origin.y > newMaximum.y) {\n return false;\n }\n } else {\n inv = 1.0 / this.direction.y;\n min = (newMinimum.y - this.origin.y) * inv;\n max = (newMaximum.y - this.origin.y) * inv;\n if (max === -Infinity) {\n max = Infinity;\n }\n if (min > max) {\n temp = min;\n min = max;\n max = temp;\n }\n d = Math.max(min, d);\n maxValue = Math.min(max, maxValue);\n if (d > maxValue) {\n return false;\n }\n }\n if (Math.abs(this.direction.z) < 0.0000001) {\n if (this.origin.z < newMinimum.z || this.origin.z > newMaximum.z) {\n return false;\n }\n } else {\n inv = 1.0 / this.direction.z;\n min = (newMinimum.z - this.origin.z) * inv;\n max = (newMaximum.z - this.origin.z) * inv;\n if (max === -Infinity) {\n max = Infinity;\n }\n if (min > max) {\n temp = min;\n min = max;\n max = temp;\n }\n d = Math.max(min, d);\n maxValue = Math.min(max, maxValue);\n if (d > maxValue) {\n return false;\n }\n }\n return true;\n }\n /**\n * Checks if the ray intersects a box\n * This does not account for the ray lenght by design to improve perfs.\n * @param box the bounding box to check\n * @param intersectionTreshold extra extend to be added to the BoundingBox in all direction\n * @returns if the box was hit\n */\n intersectsBox(box, intersectionTreshold = 0) {\n return this.intersectsBoxMinMax(box.minimum, box.maximum, intersectionTreshold);\n }\n /**\n * If the ray hits a sphere\n * @param sphere the bounding sphere to check\n * @param intersectionTreshold extra extend to be added to the BoundingSphere in all direction\n * @returns true if it hits the sphere\n */\n intersectsSphere(sphere, intersectionTreshold = 0) {\n const x = sphere.center.x - this.origin.x;\n const y = sphere.center.y - this.origin.y;\n const z = sphere.center.z - this.origin.z;\n const pyth = x * x + y * y + z * z;\n const radius = sphere.radius + intersectionTreshold;\n const rr = radius * radius;\n if (pyth <= rr) {\n return true;\n }\n const dot = x * this.direction.x + y * this.direction.y + z * this.direction.z;\n if (dot < 0.0) {\n return false;\n }\n const temp = pyth - dot * dot;\n return temp <= rr;\n }\n /**\n * If the ray hits a triange\n * @param vertex0 triangle vertex\n * @param vertex1 triangle vertex\n * @param vertex2 triangle vertex\n * @returns intersection information if hit\n */\n intersectsTriangle(vertex0, vertex1, vertex2) {\n const edge1 = Ray._TmpVector3[0];\n const edge2 = Ray._TmpVector3[1];\n const pvec = Ray._TmpVector3[2];\n const tvec = Ray._TmpVector3[3];\n const qvec = Ray._TmpVector3[4];\n vertex1.subtractToRef(vertex0, edge1);\n vertex2.subtractToRef(vertex0, edge2);\n Vector3.CrossToRef(this.direction, edge2, pvec);\n const det = Vector3.Dot(edge1, pvec);\n if (det === 0) {\n return null;\n }\n const invdet = 1 / det;\n this.origin.subtractToRef(vertex0, tvec);\n const bv = Vector3.Dot(tvec, pvec) * invdet;\n if (bv < -this.epsilon || bv > 1.0 + this.epsilon) {\n return null;\n }\n Vector3.CrossToRef(tvec, edge1, qvec);\n const bw = Vector3.Dot(this.direction, qvec) * invdet;\n if (bw < -this.epsilon || bv + bw > 1.0 + this.epsilon) {\n return null;\n }\n //check if the distance is longer than the predefined length.\n const distance = Vector3.Dot(edge2, qvec) * invdet;\n if (distance > this.length) {\n return null;\n }\n return new IntersectionInfo(1 - bv - bw, bv, distance);\n }\n /**\n * Checks if ray intersects a plane\n * @param plane the plane to check\n * @returns the distance away it was hit\n */\n intersectsPlane(plane) {\n let distance;\n const result1 = Vector3.Dot(plane.normal, this.direction);\n if (Math.abs(result1) < 9.99999997475243e-7) {\n return null;\n } else {\n const result2 = Vector3.Dot(plane.normal, this.origin);\n distance = (-plane.d - result2) / result1;\n if (distance < 0.0) {\n if (distance < -9.99999997475243e-7) {\n return null;\n } else {\n return 0;\n }\n }\n return distance;\n }\n }\n /**\n * Calculate the intercept of a ray on a given axis\n * @param axis to check 'x' | 'y' | 'z'\n * @param offset from axis interception (i.e. an offset of 1y is intercepted above ground)\n * @returns a vector containing the coordinates where 'axis' is equal to zero (else offset), or null if there is no intercept.\n */\n intersectsAxis(axis, offset = 0) {\n switch (axis) {\n case \"y\":\n {\n const t = (this.origin.y - offset) / this.direction.y;\n if (t > 0) {\n return null;\n }\n return new Vector3(this.origin.x + this.direction.x * -t, offset, this.origin.z + this.direction.z * -t);\n }\n case \"x\":\n {\n const t = (this.origin.x - offset) / this.direction.x;\n if (t > 0) {\n return null;\n }\n return new Vector3(offset, this.origin.y + this.direction.y * -t, this.origin.z + this.direction.z * -t);\n }\n case \"z\":\n {\n const t = (this.origin.z - offset) / this.direction.z;\n if (t > 0) {\n return null;\n }\n return new Vector3(this.origin.x + this.direction.x * -t, this.origin.y + this.direction.y * -t, offset);\n }\n default:\n return null;\n }\n }\n /**\n * Checks if ray intersects a mesh. The ray is defined in WORLD space. A mesh triangle can be picked both from its front and back sides,\n * irrespective of orientation.\n * @param mesh the mesh to check\n * @param fastCheck defines if the first intersection will be used (and not the closest)\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\n * @param onlyBoundingInfo defines a boolean indicating if picking should only happen using bounding info (false by default)\n * @param worldToUse defines the world matrix to use to get the world coordinate of the intersection point\n * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check\n * @returns picking info of the intersection\n */\n intersectsMesh(mesh, fastCheck, trianglePredicate, onlyBoundingInfo = false, worldToUse, skipBoundingInfo = false) {\n const tm = TmpVectors.Matrix[0];\n mesh.getWorldMatrix().invertToRef(tm);\n if (this._tmpRay) {\n Ray.TransformToRef(this, tm, this._tmpRay);\n } else {\n this._tmpRay = Ray.Transform(this, tm);\n }\n return mesh.intersects(this._tmpRay, fastCheck, trianglePredicate, onlyBoundingInfo, worldToUse, skipBoundingInfo);\n }\n /**\n * Checks if ray intersects a mesh\n * @param meshes the meshes to check\n * @param fastCheck defines if the first intersection will be used (and not the closest)\n * @param results array to store result in\n * @returns Array of picking infos\n */\n intersectsMeshes(meshes, fastCheck, results) {\n if (results) {\n results.length = 0;\n } else {\n results = [];\n }\n for (let i = 0; i < meshes.length; i++) {\n const pickInfo = this.intersectsMesh(meshes[i], fastCheck);\n if (pickInfo.hit) {\n results.push(pickInfo);\n }\n }\n results.sort(this._comparePickingInfo);\n return results;\n }\n _comparePickingInfo(pickingInfoA, pickingInfoB) {\n if (pickingInfoA.distance < pickingInfoB.distance) {\n return -1;\n } else if (pickingInfoA.distance > pickingInfoB.distance) {\n return 1;\n } else {\n return 0;\n }\n }\n /**\n * Intersection test between the ray and a given segment within a given tolerance (threshold)\n * @param sega the first point of the segment to test the intersection against\n * @param segb the second point of the segment to test the intersection against\n * @param threshold the tolerance margin, if the ray doesn't intersect the segment but is close to the given threshold, the intersection is successful\n * @returns the distance from the ray origin to the intersection point if there's intersection, or -1 if there's no intersection\n */\n intersectionSegment(sega, segb, threshold) {\n const o = this.origin;\n const u = TmpVectors.Vector3[0];\n const rsegb = TmpVectors.Vector3[1];\n const v = TmpVectors.Vector3[2];\n const w = TmpVectors.Vector3[3];\n segb.subtractToRef(sega, u);\n this.direction.scaleToRef(Ray._Rayl, v);\n o.addToRef(v, rsegb);\n sega.subtractToRef(o, w);\n const a = Vector3.Dot(u, u); // always >= 0\n const b = Vector3.Dot(u, v);\n const c = Vector3.Dot(v, v); // always >= 0\n const d = Vector3.Dot(u, w);\n const e = Vector3.Dot(v, w);\n const D = a * c - b * b; // always >= 0\n let sN,\n sD = D; // sc = sN / sD, default sD = D >= 0\n let tN,\n tD = D; // tc = tN / tD, default tD = D >= 0\n // compute the line parameters of the two closest points\n if (D < Ray._Smallnum) {\n // the lines are almost parallel\n sN = 0.0; // force using point P0 on segment S1\n sD = 1.0; // to prevent possible division by 0.0 later\n tN = e;\n tD = c;\n } else {\n // get the closest points on the infinite lines\n sN = b * e - c * d;\n tN = a * e - b * d;\n if (sN < 0.0) {\n // sc < 0 => the s=0 edge is visible\n sN = 0.0;\n tN = e;\n tD = c;\n } else if (sN > sD) {\n // sc > 1 => the s=1 edge is visible\n sN = sD;\n tN = e + b;\n tD = c;\n }\n }\n if (tN < 0.0) {\n // tc < 0 => the t=0 edge is visible\n tN = 0.0;\n // recompute sc for this edge\n if (-d < 0.0) {\n sN = 0.0;\n } else if (-d > a) {\n sN = sD;\n } else {\n sN = -d;\n sD = a;\n }\n } else if (tN > tD) {\n // tc > 1 => the t=1 edge is visible\n tN = tD;\n // recompute sc for this edge\n if (-d + b < 0.0) {\n sN = 0;\n } else if (-d + b > a) {\n sN = sD;\n } else {\n sN = -d + b;\n sD = a;\n }\n }\n // finally do the division to get sc and tc\n const sc = Math.abs(sN) < Ray._Smallnum ? 0.0 : sN / sD;\n const tc = Math.abs(tN) < Ray._Smallnum ? 0.0 : tN / tD;\n // get the difference of the two closest points\n const qtc = TmpVectors.Vector3[4];\n v.scaleToRef(tc, qtc);\n const qsc = TmpVectors.Vector3[5];\n u.scaleToRef(sc, qsc);\n qsc.addInPlace(w);\n const dP = TmpVectors.Vector3[6];\n qsc.subtractToRef(qtc, dP); // = S1(sc) - S2(tc)\n const isIntersected = tc > 0 && tc <= this.length && dP.lengthSquared() < threshold * threshold; // return intersection result\n if (isIntersected) {\n return qsc.length();\n }\n return -1;\n }\n /**\n * Update the ray from viewport position\n * @param x position\n * @param y y position\n * @param viewportWidth viewport width\n * @param viewportHeight viewport height\n * @param world world matrix\n * @param view view matrix\n * @param projection projection matrix\n * @param enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default)\n * @returns this ray updated\n */\n update(x, y, viewportWidth, viewportHeight, world, view, projection, enableDistantPicking = false) {\n if (enableDistantPicking) {\n // With world matrices having great values (like 8000000000 on 1 or more scaling or position axis),\n // multiplying view/projection/world and doing invert will result in loss of float precision in the matrix.\n // One way to fix it is to compute the ray with world at identity then transform the ray in object space.\n // This is slower (2 matrix inverts instead of 1) but precision is preserved.\n // This is hidden behind `EnableDistantPicking` flag (default is false)\n if (!Ray._RayDistant) {\n Ray._RayDistant = Ray.Zero();\n }\n Ray._RayDistant.unprojectRayToRef(x, y, viewportWidth, viewportHeight, Matrix.IdentityReadOnly, view, projection);\n const tm = TmpVectors.Matrix[0];\n world.invertToRef(tm);\n Ray.TransformToRef(Ray._RayDistant, tm, this);\n } else {\n this.unprojectRayToRef(x, y, viewportWidth, viewportHeight, world, view, projection);\n }\n return this;\n }\n // Statics\n /**\n * Creates a ray with origin and direction of 0,0,0\n * @returns the new ray\n */\n static Zero() {\n return new Ray(Vector3.Zero(), Vector3.Zero());\n }\n /**\n * Creates a new ray from screen space and viewport\n * @param x position\n * @param y y position\n * @param viewportWidth viewport width\n * @param viewportHeight viewport height\n * @param world world matrix\n * @param view view matrix\n * @param projection projection matrix\n * @returns new ray\n */\n static CreateNew(x, y, viewportWidth, viewportHeight, world, view, projection) {\n const result = Ray.Zero();\n return result.update(x, y, viewportWidth, viewportHeight, world, view, projection);\n }\n /**\n * Function will create a new transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be\n * transformed to the given world matrix.\n * @param origin The origin point\n * @param end The end point\n * @param world a matrix to transform the ray to. Default is the identity matrix.\n * @returns the new ray\n */\n static CreateNewFromTo(origin, end, world = Matrix.IdentityReadOnly) {\n const result = new Ray(new Vector3(0, 0, 0), new Vector3(0, 0, 0));\n return Ray.CreateFromToToRef(origin, end, result, world);\n }\n /**\n * Function will update a transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be\n * transformed to the given world matrix.\n * @param origin The origin point\n * @param end The end point\n * @param result the object to store the result\n * @param world a matrix to transform the ray to. Default is the identity matrix.\n * @returns the ref ray\n */\n static CreateFromToToRef(origin, end, result, world = Matrix.IdentityReadOnly) {\n result.origin.copyFrom(origin);\n const direction = end.subtractToRef(origin, result.direction);\n const length = Math.sqrt(direction.x * direction.x + direction.y * direction.y + direction.z * direction.z);\n result.length = length;\n result.direction.normalize();\n return Ray.TransformToRef(result, world, result);\n }\n /**\n * Transforms a ray by a matrix\n * @param ray ray to transform\n * @param matrix matrix to apply\n * @returns the resulting new ray\n */\n static Transform(ray, matrix) {\n const result = new Ray(new Vector3(0, 0, 0), new Vector3(0, 0, 0));\n Ray.TransformToRef(ray, matrix, result);\n return result;\n }\n /**\n * Transforms a ray by a matrix\n * @param ray ray to transform\n * @param matrix matrix to apply\n * @param result ray to store result in\n * @returns the updated result ray\n */\n static TransformToRef(ray, matrix, result) {\n Vector3.TransformCoordinatesToRef(ray.origin, matrix, result.origin);\n Vector3.TransformNormalToRef(ray.direction, matrix, result.direction);\n result.length = ray.length;\n result.epsilon = ray.epsilon;\n const dir = result.direction;\n const len = dir.length();\n if (!(len === 0 || len === 1)) {\n const num = 1.0 / len;\n dir.x *= num;\n dir.y *= num;\n dir.z *= num;\n result.length *= len;\n }\n return result;\n }\n /**\n * Unproject a ray from screen space to object space\n * @param sourceX defines the screen space x coordinate to use\n * @param sourceY defines the screen space y coordinate to use\n * @param viewportWidth defines the current width of the viewport\n * @param viewportHeight defines the current height of the viewport\n * @param world defines the world matrix to use (can be set to Identity to go to world space)\n * @param view defines the view matrix to use\n * @param projection defines the projection matrix to use\n */\n unprojectRayToRef(sourceX, sourceY, viewportWidth, viewportHeight, world, view, projection) {\n const matrix = TmpVectors.Matrix[0];\n world.multiplyToRef(view, matrix);\n matrix.multiplyToRef(projection, matrix);\n matrix.invert();\n const engine = EngineStore.LastCreatedEngine;\n const nearScreenSource = TmpVectors.Vector3[0];\n nearScreenSource.x = sourceX / viewportWidth * 2 - 1;\n nearScreenSource.y = -(sourceY / viewportHeight * 2 - 1);\n nearScreenSource.z = engine !== null && engine !== void 0 && engine.useReverseDepthBuffer ? 1 : engine !== null && engine !== void 0 && engine.isNDCHalfZRange ? 0 : -1;\n // far Z need to be close but < to 1 or camera projection matrix with maxZ = 0 will NaN\n const farScreenSource = TmpVectors.Vector3[1].copyFromFloats(nearScreenSource.x, nearScreenSource.y, 1.0 - 1e-8);\n const nearVec3 = TmpVectors.Vector3[2];\n const farVec3 = TmpVectors.Vector3[3];\n Vector3._UnprojectFromInvertedMatrixToRef(nearScreenSource, matrix, nearVec3);\n Vector3._UnprojectFromInvertedMatrixToRef(farScreenSource, matrix, farVec3);\n this.origin.copyFrom(nearVec3);\n farVec3.subtractToRef(nearVec3, this.direction);\n this.direction.normalize();\n }\n}\nRay._TmpVector3 = BuildArray(6, Vector3.Zero);\nRay._RayDistant = Ray.Zero();\nRay._Smallnum = 0.00000001;\nRay._Rayl = 10e8;\n/**\n * Creates a ray that can be used to pick in the scene\n * @param scene defines the scene to use for the picking\n * @param x defines the x coordinate of the origin (on-screen)\n * @param y defines the y coordinate of the origin (on-screen)\n * @param world defines the world matrix to use if you want to pick in object space (instead of world space)\n * @param camera defines the camera to use for the picking\n * @param cameraViewSpace defines if picking will be done in view space (false by default)\n * @returns a Ray\n */\nexport function CreatePickingRay(scene, x, y, world, camera, cameraViewSpace = false) {\n const result = Ray.Zero();\n CreatePickingRayToRef(scene, x, y, world, result, camera, cameraViewSpace);\n return result;\n}\n/**\n * Creates a ray that can be used to pick in the scene\n * @param scene defines the scene to use for the picking\n * @param x defines the x coordinate of the origin (on-screen)\n * @param y defines the y coordinate of the origin (on-screen)\n * @param world defines the world matrix to use if you want to pick in object space (instead of world space)\n * @param result defines the ray where to store the picking ray\n * @param camera defines the camera to use for the picking\n * @param cameraViewSpace defines if picking will be done in view space (false by default)\n * @param enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default)\n * @returns the current scene\n */\nexport function CreatePickingRayToRef(scene, x, y, world, result, camera, cameraViewSpace = false, enableDistantPicking = false) {\n const engine = scene.getEngine();\n if (!camera && !(camera = scene.activeCamera)) {\n return scene;\n }\n const cameraViewport = camera.viewport;\n const renderHeight = engine.getRenderHeight();\n const {\n x: vx,\n y: vy,\n width,\n height\n } = cameraViewport.toGlobal(engine.getRenderWidth(), renderHeight);\n // Moving coordinates to local viewport world\n const levelInv = 1 / engine.getHardwareScalingLevel();\n x = x * levelInv - vx;\n y = y * levelInv - (renderHeight - vy - height);\n result.update(x, y, width, height, world ? world : Matrix.IdentityReadOnly, cameraViewSpace ? Matrix.IdentityReadOnly : camera.getViewMatrix(), camera.getProjectionMatrix(), enableDistantPicking);\n return scene;\n}\n/**\n * Creates a ray that can be used to pick in the scene\n * @param scene defines the scene to use for the picking\n * @param x defines the x coordinate of the origin (on-screen)\n * @param y defines the y coordinate of the origin (on-screen)\n * @param camera defines the camera to use for the picking\n * @returns a Ray\n */\nexport function CreatePickingRayInCameraSpace(scene, x, y, camera) {\n const result = Ray.Zero();\n CreatePickingRayInCameraSpaceToRef(scene, x, y, result, camera);\n return result;\n}\n/**\n * Creates a ray that can be used to pick in the scene\n * @param scene defines the scene to use for the picking\n * @param x defines the x coordinate of the origin (on-screen)\n * @param y defines the y coordinate of the origin (on-screen)\n * @param result defines the ray where to store the picking ray\n * @param camera defines the camera to use for the picking\n * @returns the current scene\n */\nexport function CreatePickingRayInCameraSpaceToRef(scene, x, y, result, camera) {\n if (!PickingInfo) {\n return scene;\n }\n const engine = scene.getEngine();\n if (!camera && !(camera = scene.activeCamera)) {\n throw new Error(\"Active camera not set\");\n }\n const cameraViewport = camera.viewport;\n const renderHeight = engine.getRenderHeight();\n const {\n x: vx,\n y: vy,\n width,\n height\n } = cameraViewport.toGlobal(engine.getRenderWidth(), renderHeight);\n const identity = Matrix.Identity();\n // Moving coordinates to local viewport world\n const levelInv = 1 / engine.getHardwareScalingLevel();\n x = x * levelInv - vx;\n y = y * levelInv - (renderHeight - vy - height);\n result.update(x, y, width, height, identity, identity, camera.getProjectionMatrix());\n return scene;\n}\nfunction InternalPickForMesh(pickingInfo, rayFunction, mesh, world, fastCheck, onlyBoundingInfo, trianglePredicate, skipBoundingInfo) {\n const ray = rayFunction(world, mesh.enableDistantPicking);\n const result = mesh.intersects(ray, fastCheck, trianglePredicate, onlyBoundingInfo, world, skipBoundingInfo);\n if (!result || !result.hit) {\n return null;\n }\n if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance) {\n return null;\n }\n return result;\n}\nfunction InternalPick(scene, rayFunction, predicate, fastCheck, onlyBoundingInfo, trianglePredicate) {\n let pickingInfo = null;\n const computeWorldMatrixForCamera = !!(scene.activeCameras && scene.activeCameras.length > 1 && scene.cameraToUseForPointers !== scene.activeCamera);\n const currentCamera = scene.cameraToUseForPointers || scene.activeCamera;\n const picker = PickingCustomization.internalPickerForMesh || InternalPickForMesh;\n for (let meshIndex = 0; meshIndex < scene.meshes.length; meshIndex++) {\n const mesh = scene.meshes[meshIndex];\n if (predicate) {\n if (!predicate(mesh, -1)) {\n continue;\n }\n } else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {\n continue;\n }\n const forceCompute = computeWorldMatrixForCamera && mesh.isWorldMatrixCameraDependent();\n const world = mesh.computeWorldMatrix(forceCompute, currentCamera);\n if (mesh.hasThinInstances && mesh.thinInstanceEnablePicking) {\n // first check if the ray intersects the whole bounding box/sphere of the mesh\n const result = picker(pickingInfo, rayFunction, mesh, world, true, true, trianglePredicate);\n if (result) {\n if (onlyBoundingInfo) {\n // the user only asked for a bounding info check so we can return\n return result;\n }\n const tmpMatrix = TmpVectors.Matrix[1];\n const thinMatrices = mesh.thinInstanceGetWorldMatrices();\n for (let index = 0; index < thinMatrices.length; index++) {\n if (predicate && !predicate(mesh, index)) {\n continue;\n }\n const thinMatrix = thinMatrices[index];\n thinMatrix.multiplyToRef(world, tmpMatrix);\n const result = picker(pickingInfo, rayFunction, mesh, tmpMatrix, fastCheck, onlyBoundingInfo, trianglePredicate, true);\n if (result) {\n pickingInfo = result;\n pickingInfo.thinInstanceIndex = index;\n if (fastCheck) {\n return pickingInfo;\n }\n }\n }\n }\n } else {\n const result = picker(pickingInfo, rayFunction, mesh, world, fastCheck, onlyBoundingInfo, trianglePredicate);\n if (result) {\n pickingInfo = result;\n if (fastCheck) {\n return pickingInfo;\n }\n }\n }\n }\n return pickingInfo || new PickingInfo();\n}\nfunction InternalMultiPick(scene, rayFunction, predicate, trianglePredicate) {\n if (!PickingInfo) {\n return null;\n }\n const pickingInfos = [];\n const computeWorldMatrixForCamera = !!(scene.activeCameras && scene.activeCameras.length > 1 && scene.cameraToUseForPointers !== scene.activeCamera);\n const currentCamera = scene.cameraToUseForPointers || scene.activeCamera;\n const picker = PickingCustomization.internalPickerForMesh || InternalPickForMesh;\n for (let meshIndex = 0; meshIndex < scene.meshes.length; meshIndex++) {\n const mesh = scene.meshes[meshIndex];\n if (predicate) {\n if (!predicate(mesh, -1)) {\n continue;\n }\n } else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {\n continue;\n }\n const forceCompute = computeWorldMatrixForCamera && mesh.isWorldMatrixCameraDependent();\n const world = mesh.computeWorldMatrix(forceCompute, currentCamera);\n if (mesh.hasThinInstances && mesh.thinInstanceEnablePicking) {\n const result = picker(null, rayFunction, mesh, world, true, true, trianglePredicate);\n if (result) {\n const tmpMatrix = TmpVectors.Matrix[1];\n const thinMatrices = mesh.thinInstanceGetWorldMatrices();\n for (let index = 0; index < thinMatrices.length; index++) {\n if (predicate && !predicate(mesh, index)) {\n continue;\n }\n const thinMatrix = thinMatrices[index];\n thinMatrix.multiplyToRef(world, tmpMatrix);\n const result = picker(null, rayFunction, mesh, tmpMatrix, false, false, trianglePredicate, true);\n if (result) {\n result.thinInstanceIndex = index;\n pickingInfos.push(result);\n }\n }\n }\n } else {\n const result = picker(null, rayFunction, mesh, world, false, false, trianglePredicate);\n if (result) {\n pickingInfos.push(result);\n }\n }\n }\n return pickingInfos;\n}\n/** Launch a ray to try to pick a mesh in the scene using only bounding information of the main mesh (not using submeshes)\n * @param scene defines the scene to use for the picking\n * @param x position on screen\n * @param y position on screen\n * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\n * @param fastCheck defines if the first intersection will be used (and not the closest)\n * @param camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\n * @returns a PickingInfo (Please note that some info will not be set like distance, bv, bu and everything that cannot be capture by only using bounding infos)\n */\nexport function PickWithBoundingInfo(scene, x, y, predicate, fastCheck, camera) {\n if (!PickingInfo) {\n return null;\n }\n const result = InternalPick(scene, world => {\n if (!scene._tempPickingRay) {\n scene._tempPickingRay = Ray.Zero();\n }\n CreatePickingRayToRef(scene, x, y, world, scene._tempPickingRay, camera || null);\n return scene._tempPickingRay;\n }, predicate, fastCheck, true);\n if (result) {\n result.ray = CreatePickingRay(scene, x, y, Matrix.Identity(), camera || null);\n }\n return result;\n}\n/** Launch a ray to try to pick a mesh in the scene\n * @param scene defines the scene to use for the picking\n * @param x position on screen\n * @param y position on screen\n * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\n * @param fastCheck defines if the first intersection will be used (and not the closest)\n * @param camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\n * @param _enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default)\n * @returns a PickingInfo\n */\nexport function Pick(scene, x, y, predicate, fastCheck, camera, trianglePredicate, _enableDistantPicking = false) {\n const result = InternalPick(scene, (world, enableDistantPicking) => {\n if (!scene._tempPickingRay) {\n scene._tempPickingRay = Ray.Zero();\n }\n CreatePickingRayToRef(scene, x, y, world, scene._tempPickingRay, camera || null, false, enableDistantPicking);\n return scene._tempPickingRay;\n }, predicate, fastCheck, false, trianglePredicate);\n if (result) {\n result.ray = CreatePickingRay(scene, x, y, Matrix.Identity(), camera || null);\n }\n return result;\n}\n/**\n * Use the given ray to pick a mesh in the scene. A mesh triangle can be picked both from its front and back sides,\n * irrespective of orientation.\n * @param scene defines the scene to use for the picking\n * @param ray The ray to use to pick meshes\n * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must have isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\n * @param fastCheck defines if the first intersection will be used (and not the closest)\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\n * @returns a PickingInfo\n */\nexport function PickWithRay(scene, ray, predicate, fastCheck, trianglePredicate) {\n const result = InternalPick(scene, world => {\n if (!scene._pickWithRayInverseMatrix) {\n scene._pickWithRayInverseMatrix = Matrix.Identity();\n }\n world.invertToRef(scene._pickWithRayInverseMatrix);\n if (!scene._cachedRayForTransform) {\n scene._cachedRayForTransform = Ray.Zero();\n }\n Ray.TransformToRef(ray, scene._pickWithRayInverseMatrix, scene._cachedRayForTransform);\n return scene._cachedRayForTransform;\n }, predicate, fastCheck, false, trianglePredicate);\n if (result) {\n result.ray = ray;\n }\n return result;\n}\n/**\n * Launch a ray to try to pick a mesh in the scene. A mesh triangle can be picked both from its front and back sides,\n * irrespective of orientation.\n * @param scene defines the scene to use for the picking\n * @param x X position on screen\n * @param y Y position on screen\n * @param predicate Predicate function used to determine eligible meshes and instances. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\n * @param camera camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\n * @returns an array of PickingInfo\n */\nexport function MultiPick(scene, x, y, predicate, camera, trianglePredicate) {\n return InternalMultiPick(scene, world => CreatePickingRay(scene, x, y, world, camera || null), predicate, trianglePredicate);\n}\n/**\n * Launch a ray to try to pick a mesh in the scene\n * @param scene defines the scene to use for the picking\n * @param ray Ray to use\n * @param predicate Predicate function used to determine eligible meshes and instances. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\n * @returns an array of PickingInfo\n */\nexport function MultiPickWithRay(scene, ray, predicate, trianglePredicate) {\n return InternalMultiPick(scene, world => {\n if (!scene._pickWithRayInverseMatrix) {\n scene._pickWithRayInverseMatrix = Matrix.Identity();\n }\n world.invertToRef(scene._pickWithRayInverseMatrix);\n if (!scene._cachedRayForTransform) {\n scene._cachedRayForTransform = Ray.Zero();\n }\n Ray.TransformToRef(ray, scene._pickWithRayInverseMatrix, scene._cachedRayForTransform);\n return scene._cachedRayForTransform;\n }, predicate, trianglePredicate);\n}\n/**\n * Gets a ray in the forward direction from the camera.\n * @param camera Defines the camera to use to get the ray from\n * @param length Defines the length of the ray to create\n * @param transform Defines the transform to apply to the ray, by default the world matrix is used to create a workd space ray\n * @param origin Defines the start point of the ray which defaults to the camera position\n * @returns the forward ray\n */\nexport function GetForwardRay(camera, length = 100, transform, origin) {\n return GetForwardRayToRef(camera, new Ray(Vector3.Zero(), Vector3.Zero(), length), length, transform, origin);\n}\n/**\n * Gets a ray in the forward direction from the camera.\n * @param camera Defines the camera to use to get the ray from\n * @param refRay the ray to (re)use when setting the values\n * @param length Defines the length of the ray to create\n * @param transform Defines the transform to apply to the ray, by default the world matrx is used to create a workd space ray\n * @param origin Defines the start point of the ray which defaults to the camera position\n * @returns the forward ray\n */\nexport function GetForwardRayToRef(camera, refRay, length = 100, transform, origin) {\n if (!transform) {\n transform = camera.getWorldMatrix();\n }\n refRay.length = length;\n if (origin) {\n refRay.origin.copyFrom(origin);\n } else {\n refRay.origin.copyFrom(camera.position);\n }\n const forward = TmpVectors.Vector3[2];\n forward.set(0, 0, camera._scene.useRightHandedSystem ? -1 : 1);\n const worldForward = TmpVectors.Vector3[3];\n Vector3.TransformNormalToRef(forward, transform, worldForward);\n Vector3.NormalizeToRef(worldForward, refRay.direction);\n return refRay;\n}\n/**\n * Initialize the minimal interdependecies between the Ray and Scene and Camera\n * @param sceneClass defines the scene prototype to use\n * @param cameraClass defines the camera prototype to use\n */\nexport function AddRayExtensions(sceneClass, cameraClass) {\n if (cameraClass) {\n cameraClass.prototype.getForwardRay = function (length = 100, transform, origin) {\n return GetForwardRayToRef(this, new Ray(Vector3.Zero(), Vector3.Zero(), length), length, transform, origin);\n };\n cameraClass.prototype.getForwardRayToRef = function (refRay, length = 100, transform, origin) {\n return GetForwardRayToRef(this, refRay, length, transform, origin);\n };\n }\n if (!sceneClass) {\n return;\n }\n _ImportHelper._IsPickingAvailable = true;\n sceneClass.prototype.createPickingRay = function (x, y, world, camera, cameraViewSpace = false) {\n return CreatePickingRay(this, x, y, world, camera, cameraViewSpace);\n };\n}","map":{"version":3,"names":["Epsilon","Matrix","TmpVectors","Vector3","BuildArray","IntersectionInfo","PickingInfo","EngineStore","_ImportHelper","PickingCustomization","internalPickerForMesh","undefined","Ray","constructor","origin","direction","length","Number","MAX_VALUE","epsilon","clone","intersectsBoxMinMax","minimum","maximum","intersectionTreshold","newMinimum","_TmpVector3","copyFromFloats","x","y","z","newMaximum","d","maxValue","inv","min","max","temp","Math","abs","Infinity","intersectsBox","box","intersectsSphere","sphere","center","pyth","radius","rr","dot","intersectsTriangle","vertex0","vertex1","vertex2","edge1","edge2","pvec","tvec","qvec","subtractToRef","CrossToRef","det","Dot","invdet","bv","bw","distance","intersectsPlane","plane","result1","normal","result2","intersectsAxis","axis","offset","t","intersectsMesh","mesh","fastCheck","trianglePredicate","onlyBoundingInfo","worldToUse","skipBoundingInfo","tm","getWorldMatrix","invertToRef","_tmpRay","TransformToRef","Transform","intersects","intersectsMeshes","meshes","results","i","pickInfo","hit","push","sort","_comparePickingInfo","pickingInfoA","pickingInfoB","intersectionSegment","sega","segb","threshold","o","u","rsegb","v","w","scaleToRef","_Rayl","addToRef","a","b","c","e","D","sN","sD","tN","tD","_Smallnum","sc","tc","qtc","qsc","addInPlace","dP","isIntersected","lengthSquared","update","viewportWidth","viewportHeight","world","view","projection","enableDistantPicking","_RayDistant","Zero","unprojectRayToRef","IdentityReadOnly","CreateNew","result","CreateNewFromTo","end","CreateFromToToRef","copyFrom","sqrt","normalize","ray","matrix","TransformCoordinatesToRef","TransformNormalToRef","dir","len","num","sourceX","sourceY","multiplyToRef","invert","engine","LastCreatedEngine","nearScreenSource","useReverseDepthBuffer","isNDCHalfZRange","farScreenSource","nearVec3","farVec3","_UnprojectFromInvertedMatrixToRef","CreatePickingRay","scene","camera","cameraViewSpace","CreatePickingRayToRef","getEngine","activeCamera","cameraViewport","viewport","renderHeight","getRenderHeight","vx","vy","width","height","toGlobal","getRenderWidth","levelInv","getHardwareScalingLevel","getViewMatrix","getProjectionMatrix","CreatePickingRayInCameraSpace","CreatePickingRayInCameraSpaceToRef","Error","identity","Identity","InternalPickForMesh","pickingInfo","rayFunction","InternalPick","predicate","computeWorldMatrixForCamera","activeCameras","cameraToUseForPointers","currentCamera","picker","meshIndex","isEnabled","isVisible","isPickable","forceCompute","isWorldMatrixCameraDependent","computeWorldMatrix","hasThinInstances","thinInstanceEnablePicking","tmpMatrix","thinMatrices","thinInstanceGetWorldMatrices","index","thinMatrix","thinInstanceIndex","InternalMultiPick","pickingInfos","PickWithBoundingInfo","_tempPickingRay","Pick","_enableDistantPicking","PickWithRay","_pickWithRayInverseMatrix","_cachedRayForTransform","MultiPick","MultiPickWithRay","GetForwardRay","transform","GetForwardRayToRef","refRay","position","forward","set","_scene","useRightHandedSystem","worldForward","NormalizeToRef","AddRayExtensions","sceneClass","cameraClass","prototype","getForwardRay","getForwardRayToRef","_IsPickingAvailable","createPickingRay"],"sources":["F:/workspace/202226701027/huinongbao-app/node_modules/@babylonjs/core/Culling/ray.core.js"],"sourcesContent":["import { Epsilon } from \"../Maths/math.constants.js\";\nimport { Matrix, TmpVectors, Vector3 } from \"../Maths/math.vector.js\";\nimport { BuildArray } from \"../Misc/arrayTools.js\";\nimport { IntersectionInfo } from \"../Collisions/intersectionInfo.js\";\nimport { PickingInfo } from \"../Collisions/pickingInfo.js\";\nimport { EngineStore } from \"../Engines/engineStore.js\";\nimport { _ImportHelper } from \"../import.helper.js\";\n/**\n * Use this object to customize mesh picking behavior\n */\nexport const PickingCustomization = {\n internalPickerForMesh: undefined,\n};\n/**\n * Class representing a ray with position and direction\n */\nexport class Ray {\n /**\n * Creates a new ray\n * @param origin origin point\n * @param direction direction\n * @param length length of the ray\n * @param epsilon The epsilon value to use when calculating the ray/triangle intersection (default: 0)\n */\n constructor(\n /** origin point */\n origin, \n /** direction */\n direction, \n /** [Number.MAX_VALUE] length of the ray */\n length = Number.MAX_VALUE, \n /** [Epsilon] The epsilon value to use when calculating the ray/triangle intersection (default: Epsilon from math constants) */\n epsilon = Epsilon) {\n this.origin = origin;\n this.direction = direction;\n this.length = length;\n this.epsilon = epsilon;\n }\n // Methods\n /**\n * Clone the current ray\n * @returns a new ray\n */\n clone() {\n return new Ray(this.origin.clone(), this.direction.clone(), this.length);\n }\n /**\n * Checks if the ray intersects a box\n * This does not account for the ray length by design to improve perfs.\n * @param minimum bound of the box\n * @param maximum bound of the box\n * @param intersectionTreshold extra extend to be added to the box in all direction\n * @returns if the box was hit\n */\n intersectsBoxMinMax(minimum, maximum, intersectionTreshold = 0) {\n const newMinimum = Ray._TmpVector3[0].copyFromFloats(minimum.x - intersectionTreshold, minimum.y - intersectionTreshold, minimum.z - intersectionTreshold);\n const newMaximum = Ray._TmpVector3[1].copyFromFloats(maximum.x + intersectionTreshold, maximum.y + intersectionTreshold, maximum.z + intersectionTreshold);\n let d = 0.0;\n let maxValue = Number.MAX_VALUE;\n let inv;\n let min;\n let max;\n let temp;\n if (Math.abs(this.direction.x) < 0.0000001) {\n if (this.origin.x < newMinimum.x || this.origin.x > newMaximum.x) {\n return false;\n }\n }\n else {\n inv = 1.0 / this.direction.x;\n min = (newMinimum.x - this.origin.x) * inv;\n max = (newMaximum.x - this.origin.x) * inv;\n if (max === -Infinity) {\n max = Infinity;\n }\n if (min > max) {\n temp = min;\n min = max;\n max = temp;\n }\n d = Math.max(min, d);\n maxValue = Math.min(max, maxValue);\n if (d > maxValue) {\n return false;\n }\n }\n if (Math.abs(this.direction.y) < 0.0000001) {\n if (this.origin.y < newMinimum.y || this.origin.y > newMaximum.y) {\n return false;\n }\n }\n else {\n inv = 1.0 / this.direction.y;\n min = (newMinimum.y - this.origin.y) * inv;\n max = (newMaximum.y - this.origin.y) * inv;\n if (max === -Infinity) {\n max = Infinity;\n }\n if (min > max) {\n temp = min;\n min = max;\n max = temp;\n }\n d = Math.max(min, d);\n maxValue = Math.min(max, maxValue);\n if (d > maxValue) {\n return false;\n }\n }\n if (Math.abs(this.direction.z) < 0.0000001) {\n if (this.origin.z < newMinimum.z || this.origin.z > newMaximum.z) {\n return false;\n }\n }\n else {\n inv = 1.0 / this.direction.z;\n min = (newMinimum.z - this.origin.z) * inv;\n max = (newMaximum.z - this.origin.z) * inv;\n if (max === -Infinity) {\n max = Infinity;\n }\n if (min > max) {\n temp = min;\n min = max;\n max = temp;\n }\n d = Math.max(min, d);\n maxValue = Math.min(max, maxValue);\n if (d > maxValue) {\n return false;\n }\n }\n return true;\n }\n /**\n * Checks if the ray intersects a box\n * This does not account for the ray lenght by design to improve perfs.\n * @param box the bounding box to check\n * @param intersectionTreshold extra extend to be added to the BoundingBox in all direction\n * @returns if the box was hit\n */\n intersectsBox(box, intersectionTreshold = 0) {\n return this.intersectsBoxMinMax(box.minimum, box.maximum, intersectionTreshold);\n }\n /**\n * If the ray hits a sphere\n * @param sphere the bounding sphere to check\n * @param intersectionTreshold extra extend to be added to the BoundingSphere in all direction\n * @returns true if it hits the sphere\n */\n intersectsSphere(sphere, intersectionTreshold = 0) {\n const x = sphere.center.x - this.origin.x;\n const y = sphere.center.y - this.origin.y;\n const z = sphere.center.z - this.origin.z;\n const pyth = x * x + y * y + z * z;\n const radius = sphere.radius + intersectionTreshold;\n const rr = radius * radius;\n if (pyth <= rr) {\n return true;\n }\n const dot = x * this.direction.x + y * this.direction.y + z * this.direction.z;\n if (dot < 0.0) {\n return false;\n }\n const temp = pyth - dot * dot;\n return temp <= rr;\n }\n /**\n * If the ray hits a triange\n * @param vertex0 triangle vertex\n * @param vertex1 triangle vertex\n * @param vertex2 triangle vertex\n * @returns intersection information if hit\n */\n intersectsTriangle(vertex0, vertex1, vertex2) {\n const edge1 = Ray._TmpVector3[0];\n const edge2 = Ray._TmpVector3[1];\n const pvec = Ray._TmpVector3[2];\n const tvec = Ray._TmpVector3[3];\n const qvec = Ray._TmpVector3[4];\n vertex1.subtractToRef(vertex0, edge1);\n vertex2.subtractToRef(vertex0, edge2);\n Vector3.CrossToRef(this.direction, edge2, pvec);\n const det = Vector3.Dot(edge1, pvec);\n if (det === 0) {\n return null;\n }\n const invdet = 1 / det;\n this.origin.subtractToRef(vertex0, tvec);\n const bv = Vector3.Dot(tvec, pvec) * invdet;\n if (bv < -this.epsilon || bv > 1.0 + this.epsilon) {\n return null;\n }\n Vector3.CrossToRef(tvec, edge1, qvec);\n const bw = Vector3.Dot(this.direction, qvec) * invdet;\n if (bw < -this.epsilon || bv + bw > 1.0 + this.epsilon) {\n return null;\n }\n //check if the distance is longer than the predefined length.\n const distance = Vector3.Dot(edge2, qvec) * invdet;\n if (distance > this.length) {\n return null;\n }\n return new IntersectionInfo(1 - bv - bw, bv, distance);\n }\n /**\n * Checks if ray intersects a plane\n * @param plane the plane to check\n * @returns the distance away it was hit\n */\n intersectsPlane(plane) {\n let distance;\n const result1 = Vector3.Dot(plane.normal, this.direction);\n if (Math.abs(result1) < 9.99999997475243e-7) {\n return null;\n }\n else {\n const result2 = Vector3.Dot(plane.normal, this.origin);\n distance = (-plane.d - result2) / result1;\n if (distance < 0.0) {\n if (distance < -9.99999997475243e-7) {\n return null;\n }\n else {\n return 0;\n }\n }\n return distance;\n }\n }\n /**\n * Calculate the intercept of a ray on a given axis\n * @param axis to check 'x' | 'y' | 'z'\n * @param offset from axis interception (i.e. an offset of 1y is intercepted above ground)\n * @returns a vector containing the coordinates where 'axis' is equal to zero (else offset), or null if there is no intercept.\n */\n intersectsAxis(axis, offset = 0) {\n switch (axis) {\n case \"y\": {\n const t = (this.origin.y - offset) / this.direction.y;\n if (t > 0) {\n return null;\n }\n return new Vector3(this.origin.x + this.direction.x * -t, offset, this.origin.z + this.direction.z * -t);\n }\n case \"x\": {\n const t = (this.origin.x - offset) / this.direction.x;\n if (t > 0) {\n return null;\n }\n return new Vector3(offset, this.origin.y + this.direction.y * -t, this.origin.z + this.direction.z * -t);\n }\n case \"z\": {\n const t = (this.origin.z - offset) / this.direction.z;\n if (t > 0) {\n return null;\n }\n return new Vector3(this.origin.x + this.direction.x * -t, this.origin.y + this.direction.y * -t, offset);\n }\n default:\n return null;\n }\n }\n /**\n * Checks if ray intersects a mesh. The ray is defined in WORLD space. A mesh triangle can be picked both from its front and back sides,\n * irrespective of orientation.\n * @param mesh the mesh to check\n * @param fastCheck defines if the first intersection will be used (and not the closest)\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\n * @param onlyBoundingInfo defines a boolean indicating if picking should only happen using bounding info (false by default)\n * @param worldToUse defines the world matrix to use to get the world coordinate of the intersection point\n * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check\n * @returns picking info of the intersection\n */\n intersectsMesh(mesh, fastCheck, trianglePredicate, onlyBoundingInfo = false, worldToUse, skipBoundingInfo = false) {\n const tm = TmpVectors.Matrix[0];\n mesh.getWorldMatrix().invertToRef(tm);\n if (this._tmpRay) {\n Ray.TransformToRef(this, tm, this._tmpRay);\n }\n else {\n this._tmpRay = Ray.Transform(this, tm);\n }\n return mesh.intersects(this._tmpRay, fastCheck, trianglePredicate, onlyBoundingInfo, worldToUse, skipBoundingInfo);\n }\n /**\n * Checks if ray intersects a mesh\n * @param meshes the meshes to check\n * @param fastCheck defines if the first intersection will be used (and not the closest)\n * @param results array to store result in\n * @returns Array of picking infos\n */\n intersectsMeshes(meshes, fastCheck, results) {\n if (results) {\n results.length = 0;\n }\n else {\n results = [];\n }\n for (let i = 0; i < meshes.length; i++) {\n const pickInfo = this.intersectsMesh(meshes[i], fastCheck);\n if (pickInfo.hit) {\n results.push(pickInfo);\n }\n }\n results.sort(this._comparePickingInfo);\n return results;\n }\n _comparePickingInfo(pickingInfoA, pickingInfoB) {\n if (pickingInfoA.distance < pickingInfoB.distance) {\n return -1;\n }\n else if (pickingInfoA.distance > pickingInfoB.distance) {\n return 1;\n }\n else {\n return 0;\n }\n }\n /**\n * Intersection test between the ray and a given segment within a given tolerance (threshold)\n * @param sega the first point of the segment to test the intersection against\n * @param segb the second point of the segment to test the intersection against\n * @param threshold the tolerance margin, if the ray doesn't intersect the segment but is close to the given threshold, the intersection is successful\n * @returns the distance from the ray origin to the intersection point if there's intersection, or -1 if there's no intersection\n */\n intersectionSegment(sega, segb, threshold) {\n const o = this.origin;\n const u = TmpVectors.Vector3[0];\n const rsegb = TmpVectors.Vector3[1];\n const v = TmpVectors.Vector3[2];\n const w = TmpVectors.Vector3[3];\n segb.subtractToRef(sega, u);\n this.direction.scaleToRef(Ray._Rayl, v);\n o.addToRef(v, rsegb);\n sega.subtractToRef(o, w);\n const a = Vector3.Dot(u, u); // always >= 0\n const b = Vector3.Dot(u, v);\n const c = Vector3.Dot(v, v); // always >= 0\n const d = Vector3.Dot(u, w);\n const e = Vector3.Dot(v, w);\n const D = a * c - b * b; // always >= 0\n let sN, sD = D; // sc = sN / sD, default sD = D >= 0\n let tN, tD = D; // tc = tN / tD, default tD = D >= 0\n // compute the line parameters of the two closest points\n if (D < Ray._Smallnum) {\n // the lines are almost parallel\n sN = 0.0; // force using point P0 on segment S1\n sD = 1.0; // to prevent possible division by 0.0 later\n tN = e;\n tD = c;\n }\n else {\n // get the closest points on the infinite lines\n sN = b * e - c * d;\n tN = a * e - b * d;\n if (sN < 0.0) {\n // sc < 0 => the s=0 edge is visible\n sN = 0.0;\n tN = e;\n tD = c;\n }\n else if (sN > sD) {\n // sc > 1 => the s=1 edge is visible\n sN = sD;\n tN = e + b;\n tD = c;\n }\n }\n if (tN < 0.0) {\n // tc < 0 => the t=0 edge is visible\n tN = 0.0;\n // recompute sc for this edge\n if (-d < 0.0) {\n sN = 0.0;\n }\n else if (-d > a) {\n sN = sD;\n }\n else {\n sN = -d;\n sD = a;\n }\n }\n else if (tN > tD) {\n // tc > 1 => the t=1 edge is visible\n tN = tD;\n // recompute sc for this edge\n if (-d + b < 0.0) {\n sN = 0;\n }\n else if (-d + b > a) {\n sN = sD;\n }\n else {\n sN = -d + b;\n sD = a;\n }\n }\n // finally do the division to get sc and tc\n const sc = Math.abs(sN) < Ray._Smallnum ? 0.0 : sN / sD;\n const tc = Math.abs(tN) < Ray._Smallnum ? 0.0 : tN / tD;\n // get the difference of the two closest points\n const qtc = TmpVectors.Vector3[4];\n v.scaleToRef(tc, qtc);\n const qsc = TmpVectors.Vector3[5];\n u.scaleToRef(sc, qsc);\n qsc.addInPlace(w);\n const dP = TmpVectors.Vector3[6];\n qsc.subtractToRef(qtc, dP); // = S1(sc) - S2(tc)\n const isIntersected = tc > 0 && tc <= this.length && dP.lengthSquared() < threshold * threshold; // return intersection result\n if (isIntersected) {\n return qsc.length();\n }\n return -1;\n }\n /**\n * Update the ray from viewport position\n * @param x position\n * @param y y position\n * @param viewportWidth viewport width\n * @param viewportHeight viewport height\n * @param world world matrix\n * @param view view matrix\n * @param projection projection matrix\n * @param enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default)\n * @returns this ray updated\n */\n update(x, y, viewportWidth, viewportHeight, world, view, projection, enableDistantPicking = false) {\n if (enableDistantPicking) {\n // With world matrices having great values (like 8000000000 on 1 or more scaling or position axis),\n // multiplying view/projection/world and doing invert will result in loss of float precision in the matrix.\n // One way to fix it is to compute the ray with world at identity then transform the ray in object space.\n // This is slower (2 matrix inverts instead of 1) but precision is preserved.\n // This is hidden behind `EnableDistantPicking` flag (default is false)\n if (!Ray._RayDistant) {\n Ray._RayDistant = Ray.Zero();\n }\n Ray._RayDistant.unprojectRayToRef(x, y, viewportWidth, viewportHeight, Matrix.IdentityReadOnly, view, projection);\n const tm = TmpVectors.Matrix[0];\n world.invertToRef(tm);\n Ray.TransformToRef(Ray._RayDistant, tm, this);\n }\n else {\n this.unprojectRayToRef(x, y, viewportWidth, viewportHeight, world, view, projection);\n }\n return this;\n }\n // Statics\n /**\n * Creates a ray with origin and direction of 0,0,0\n * @returns the new ray\n */\n static Zero() {\n return new Ray(Vector3.Zero(), Vector3.Zero());\n }\n /**\n * Creates a new ray from screen space and viewport\n * @param x position\n * @param y y position\n * @param viewportWidth viewport width\n * @param viewportHeight viewport height\n * @param world world matrix\n * @param view view matrix\n * @param projection projection matrix\n * @returns new ray\n */\n static CreateNew(x, y, viewportWidth, viewportHeight, world, view, projection) {\n const result = Ray.Zero();\n return result.update(x, y, viewportWidth, viewportHeight, world, view, projection);\n }\n /**\n * Function will create a new transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be\n * transformed to the given world matrix.\n * @param origin The origin point\n * @param end The end point\n * @param world a matrix to transform the ray to. Default is the identity matrix.\n * @returns the new ray\n */\n static CreateNewFromTo(origin, end, world = Matrix.IdentityReadOnly) {\n const result = new Ray(new Vector3(0, 0, 0), new Vector3(0, 0, 0));\n return Ray.CreateFromToToRef(origin, end, result, world);\n }\n /**\n * Function will update a transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be\n * transformed to the given world matrix.\n * @param origin The origin point\n * @param end The end point\n * @param result the object to store the result\n * @param world a matrix to transform the ray to. Default is the identity matrix.\n * @returns the ref ray\n */\n static CreateFromToToRef(origin, end, result, world = Matrix.IdentityReadOnly) {\n result.origin.copyFrom(origin);\n const direction = end.subtractToRef(origin, result.direction);\n const length = Math.sqrt(direction.x * direction.x + direction.y * direction.y + direction.z * direction.z);\n result.length = length;\n result.direction.normalize();\n return Ray.TransformToRef(result, world, result);\n }\n /**\n * Transforms a ray by a matrix\n * @param ray ray to transform\n * @param matrix matrix to apply\n * @returns the resulting new ray\n */\n static Transform(ray, matrix) {\n const result = new Ray(new Vector3(0, 0, 0), new Vector3(0, 0, 0));\n Ray.TransformToRef(ray, matrix, result);\n return result;\n }\n /**\n * Transforms a ray by a matrix\n * @param ray ray to transform\n * @param matrix matrix to apply\n * @param result ray to store result in\n * @returns the updated result ray\n */\n static TransformToRef(ray, matrix, result) {\n Vector3.TransformCoordinatesToRef(ray.origin, matrix, result.origin);\n Vector3.TransformNormalToRef(ray.direction, matrix, result.direction);\n result.length = ray.length;\n result.epsilon = ray.epsilon;\n const dir = result.direction;\n const len = dir.length();\n if (!(len === 0 || len === 1)) {\n const num = 1.0 / len;\n dir.x *= num;\n dir.y *= num;\n dir.z *= num;\n result.length *= len;\n }\n return result;\n }\n /**\n * Unproject a ray from screen space to object space\n * @param sourceX defines the screen space x coordinate to use\n * @param sourceY defines the screen space y coordinate to use\n * @param viewportWidth defines the current width of the viewport\n * @param viewportHeight defines the current height of the viewport\n * @param world defines the world matrix to use (can be set to Identity to go to world space)\n * @param view defines the view matrix to use\n * @param projection defines the projection matrix to use\n */\n unprojectRayToRef(sourceX, sourceY, viewportWidth, viewportHeight, world, view, projection) {\n const matrix = TmpVectors.Matrix[0];\n world.multiplyToRef(view, matrix);\n matrix.multiplyToRef(projection, matrix);\n matrix.invert();\n const engine = EngineStore.LastCreatedEngine;\n const nearScreenSource = TmpVectors.Vector3[0];\n nearScreenSource.x = (sourceX / viewportWidth) * 2 - 1;\n nearScreenSource.y = -((sourceY / viewportHeight) * 2 - 1);\n nearScreenSource.z = engine?.useReverseDepthBuffer ? 1 : engine?.isNDCHalfZRange ? 0 : -1;\n // far Z need to be close but < to 1 or camera projection matrix with maxZ = 0 will NaN\n const farScreenSource = TmpVectors.Vector3[1].copyFromFloats(nearScreenSource.x, nearScreenSource.y, 1.0 - 1e-8);\n const nearVec3 = TmpVectors.Vector3[2];\n const farVec3 = TmpVectors.Vector3[3];\n Vector3._UnprojectFromInvertedMatrixToRef(nearScreenSource, matrix, nearVec3);\n Vector3._UnprojectFromInvertedMatrixToRef(farScreenSource, matrix, farVec3);\n this.origin.copyFrom(nearVec3);\n farVec3.subtractToRef(nearVec3, this.direction);\n this.direction.normalize();\n }\n}\nRay._TmpVector3 = BuildArray(6, Vector3.Zero);\nRay._RayDistant = Ray.Zero();\nRay._Smallnum = 0.00000001;\nRay._Rayl = 10e8;\n/**\n * Creates a ray that can be used to pick in the scene\n * @param scene defines the scene to use for the picking\n * @param x defines the x coordinate of the origin (on-screen)\n * @param y defines the y coordinate of the origin (on-screen)\n * @param world defines the world matrix to use if you want to pick in object space (instead of world space)\n * @param camera defines the camera to use for the picking\n * @param cameraViewSpace defines if picking will be done in view space (false by default)\n * @returns a Ray\n */\nexport function CreatePickingRay(scene, x, y, world, camera, cameraViewSpace = false) {\n const result = Ray.Zero();\n CreatePickingRayToRef(scene, x, y, world, result, camera, cameraViewSpace);\n return result;\n}\n/**\n * Creates a ray that can be used to pick in the scene\n * @param scene defines the scene to use for the picking\n * @param x defines the x coordinate of the origin (on-screen)\n * @param y defines the y coordinate of the origin (on-screen)\n * @param world defines the world matrix to use if you want to pick in object space (instead of world space)\n * @param result defines the ray where to store the picking ray\n * @param camera defines the camera to use for the picking\n * @param cameraViewSpace defines if picking will be done in view space (false by default)\n * @param enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default)\n * @returns the current scene\n */\nexport function CreatePickingRayToRef(scene, x, y, world, result, camera, cameraViewSpace = false, enableDistantPicking = false) {\n const engine = scene.getEngine();\n if (!camera && !(camera = scene.activeCamera)) {\n return scene;\n }\n const cameraViewport = camera.viewport;\n const renderHeight = engine.getRenderHeight();\n const { x: vx, y: vy, width, height } = cameraViewport.toGlobal(engine.getRenderWidth(), renderHeight);\n // Moving coordinates to local viewport world\n const levelInv = 1 / engine.getHardwareScalingLevel();\n x = x * levelInv - vx;\n y = y * levelInv - (renderHeight - vy - height);\n result.update(x, y, width, height, world ? world : Matrix.IdentityReadOnly, cameraViewSpace ? Matrix.IdentityReadOnly : camera.getViewMatrix(), camera.getProjectionMatrix(), enableDistantPicking);\n return scene;\n}\n/**\n * Creates a ray that can be used to pick in the scene\n * @param scene defines the scene to use for the picking\n * @param x defines the x coordinate of the origin (on-screen)\n * @param y defines the y coordinate of the origin (on-screen)\n * @param camera defines the camera to use for the picking\n * @returns a Ray\n */\nexport function CreatePickingRayInCameraSpace(scene, x, y, camera) {\n const result = Ray.Zero();\n CreatePickingRayInCameraSpaceToRef(scene, x, y, result, camera);\n return result;\n}\n/**\n * Creates a ray that can be used to pick in the scene\n * @param scene defines the scene to use for the picking\n * @param x defines the x coordinate of the origin (on-screen)\n * @param y defines the y coordinate of the origin (on-screen)\n * @param result defines the ray where to store the picking ray\n * @param camera defines the camera to use for the picking\n * @returns the current scene\n */\nexport function CreatePickingRayInCameraSpaceToRef(scene, x, y, result, camera) {\n if (!PickingInfo) {\n return scene;\n }\n const engine = scene.getEngine();\n if (!camera && !(camera = scene.activeCamera)) {\n throw new Error(\"Active camera not set\");\n }\n const cameraViewport = camera.viewport;\n const renderHeight = engine.getRenderHeight();\n const { x: vx, y: vy, width, height } = cameraViewport.toGlobal(engine.getRenderWidth(), renderHeight);\n const identity = Matrix.Identity();\n // Moving coordinates to local viewport world\n const levelInv = 1 / engine.getHardwareScalingLevel();\n x = x * levelInv - vx;\n y = y * levelInv - (renderHeight - vy - height);\n result.update(x, y, width, height, identity, identity, camera.getProjectionMatrix());\n return scene;\n}\nfunction InternalPickForMesh(pickingInfo, rayFunction, mesh, world, fastCheck, onlyBoundingInfo, trianglePredicate, skipBoundingInfo) {\n const ray = rayFunction(world, mesh.enableDistantPicking);\n const result = mesh.intersects(ray, fastCheck, trianglePredicate, onlyBoundingInfo, world, skipBoundingInfo);\n if (!result || !result.hit) {\n return null;\n }\n if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance) {\n return null;\n }\n return result;\n}\nfunction InternalPick(scene, rayFunction, predicate, fastCheck, onlyBoundingInfo, trianglePredicate) {\n let pickingInfo = null;\n const computeWorldMatrixForCamera = !!(scene.activeCameras && scene.activeCameras.length > 1 && scene.cameraToUseForPointers !== scene.activeCamera);\n const currentCamera = scene.cameraToUseForPointers || scene.activeCamera;\n const picker = PickingCustomization.internalPickerForMesh || InternalPickForMesh;\n for (let meshIndex = 0; meshIndex < scene.meshes.length; meshIndex++) {\n const mesh = scene.meshes[meshIndex];\n if (predicate) {\n if (!predicate(mesh, -1)) {\n continue;\n }\n }\n else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {\n continue;\n }\n const forceCompute = computeWorldMatrixForCamera && mesh.isWorldMatrixCameraDependent();\n const world = mesh.computeWorldMatrix(forceCompute, currentCamera);\n if (mesh.hasThinInstances && mesh.thinInstanceEnablePicking) {\n // first check if the ray intersects the whole bounding box/sphere of the mesh\n const result = picker(pickingInfo, rayFunction, mesh, world, true, true, trianglePredicate);\n if (result) {\n if (onlyBoundingInfo) {\n // the user only asked for a bounding info check so we can return\n return result;\n }\n const tmpMatrix = TmpVectors.Matrix[1];\n const thinMatrices = mesh.thinInstanceGetWorldMatrices();\n for (let index = 0; index < thinMatrices.length; index++) {\n if (predicate && !predicate(mesh, index)) {\n continue;\n }\n const thinMatrix = thinMatrices[index];\n thinMatrix.multiplyToRef(world, tmpMatrix);\n const result = picker(pickingInfo, rayFunction, mesh, tmpMatrix, fastCheck, onlyBoundingInfo, trianglePredicate, true);\n if (result) {\n pickingInfo = result;\n pickingInfo.thinInstanceIndex = index;\n if (fastCheck) {\n return pickingInfo;\n }\n }\n }\n }\n }\n else {\n const result = picker(pickingInfo, rayFunction, mesh, world, fastCheck, onlyBoundingInfo, trianglePredicate);\n if (result) {\n pickingInfo = result;\n if (fastCheck) {\n return pickingInfo;\n }\n }\n }\n }\n return pickingInfo || new PickingInfo();\n}\nfunction InternalMultiPick(scene, rayFunction, predicate, trianglePredicate) {\n if (!PickingInfo) {\n return null;\n }\n const pickingInfos = [];\n const computeWorldMatrixForCamera = !!(scene.activeCameras && scene.activeCameras.length > 1 && scene.cameraToUseForPointers !== scene.activeCamera);\n const currentCamera = scene.cameraToUseForPointers || scene.activeCamera;\n const picker = PickingCustomization.internalPickerForMesh || InternalPickForMesh;\n for (let meshIndex = 0; meshIndex < scene.meshes.length; meshIndex++) {\n const mesh = scene.meshes[meshIndex];\n if (predicate) {\n if (!predicate(mesh, -1)) {\n continue;\n }\n }\n else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {\n continue;\n }\n const forceCompute = computeWorldMatrixForCamera && mesh.isWorldMatrixCameraDependent();\n const world = mesh.computeWorldMatrix(forceCompute, currentCamera);\n if (mesh.hasThinInstances && mesh.thinInstanceEnablePicking) {\n const result = picker(null, rayFunction, mesh, world, true, true, trianglePredicate);\n if (result) {\n const tmpMatrix = TmpVectors.Matrix[1];\n const thinMatrices = mesh.thinInstanceGetWorldMatrices();\n for (let index = 0; index < thinMatrices.length; index++) {\n if (predicate && !predicate(mesh, index)) {\n continue;\n }\n const thinMatrix = thinMatrices[index];\n thinMatrix.multiplyToRef(world, tmpMatrix);\n const result = picker(null, rayFunction, mesh, tmpMatrix, false, false, trianglePredicate, true);\n if (result) {\n result.thinInstanceIndex = index;\n pickingInfos.push(result);\n }\n }\n }\n }\n else {\n const result = picker(null, rayFunction, mesh, world, false, false, trianglePredicate);\n if (result) {\n pickingInfos.push(result);\n }\n }\n }\n return pickingInfos;\n}\n/** Launch a ray to try to pick a mesh in the scene using only bounding information of the main mesh (not using submeshes)\n * @param scene defines the scene to use for the picking\n * @param x position on screen\n * @param y position on screen\n * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\n * @param fastCheck defines if the first intersection will be used (and not the closest)\n * @param camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\n * @returns a PickingInfo (Please note that some info will not be set like distance, bv, bu and everything that cannot be capture by only using bounding infos)\n */\nexport function PickWithBoundingInfo(scene, x, y, predicate, fastCheck, camera) {\n if (!PickingInfo) {\n return null;\n }\n const result = InternalPick(scene, (world) => {\n if (!scene._tempPickingRay) {\n scene._tempPickingRay = Ray.Zero();\n }\n CreatePickingRayToRef(scene, x, y, world, scene._tempPickingRay, camera || null);\n return scene._tempPickingRay;\n }, predicate, fastCheck, true);\n if (result) {\n result.ray = CreatePickingRay(scene, x, y, Matrix.Identity(), camera || null);\n }\n return result;\n}\n/** Launch a ray to try to pick a mesh in the scene\n * @param scene defines the scene to use for the picking\n * @param x position on screen\n * @param y position on screen\n * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\n * @param fastCheck defines if the first intersection will be used (and not the closest)\n * @param camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\n * @param _enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default)\n * @returns a PickingInfo\n */\nexport function Pick(scene, x, y, predicate, fastCheck, camera, trianglePredicate, _enableDistantPicking = false) {\n const result = InternalPick(scene, (world, enableDistantPicking) => {\n if (!scene._tempPickingRay) {\n scene._tempPickingRay = Ray.Zero();\n }\n CreatePickingRayToRef(scene, x, y, world, scene._tempPickingRay, camera || null, false, enableDistantPicking);\n return scene._tempPickingRay;\n }, predicate, fastCheck, false, trianglePredicate);\n if (result) {\n result.ray = CreatePickingRay(scene, x, y, Matrix.Identity(), camera || null);\n }\n return result;\n}\n/**\n * Use the given ray to pick a mesh in the scene. A mesh triangle can be picked both from its front and back sides,\n * irrespective of orientation.\n * @param scene defines the scene to use for the picking\n * @param ray The ray to use to pick meshes\n * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must have isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\n * @param fastCheck defines if the first intersection will be used (and not the closest)\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\n * @returns a PickingInfo\n */\nexport function PickWithRay(scene, ray, predicate, fastCheck, trianglePredicate) {\n const result = InternalPick(scene, (world) => {\n if (!scene._pickWithRayInverseMatrix) {\n scene._pickWithRayInverseMatrix = Matrix.Identity();\n }\n world.invertToRef(scene._pickWithRayInverseMatrix);\n if (!scene._cachedRayForTransform) {\n scene._cachedRayForTransform = Ray.Zero();\n }\n Ray.TransformToRef(ray, scene._pickWithRayInverseMatrix, scene._cachedRayForTransform);\n return scene._cachedRayForTransform;\n }, predicate, fastCheck, false, trianglePredicate);\n if (result) {\n result.ray = ray;\n }\n return result;\n}\n/**\n * Launch a ray to try to pick a mesh in the scene. A mesh triangle can be picked both from its front and back sides,\n * irrespective of orientation.\n * @param scene defines the scene to use for the picking\n * @param x X position on screen\n * @param y Y position on screen\n * @param predicate Predicate function used to determine eligible meshes and instances. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\n * @param camera camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\n * @returns an array of PickingInfo\n */\nexport function MultiPick(scene, x, y, predicate, camera, trianglePredicate) {\n return InternalMultiPick(scene, (world) => CreatePickingRay(scene, x, y, world, camera || null), predicate, trianglePredicate);\n}\n/**\n * Launch a ray to try to pick a mesh in the scene\n * @param scene defines the scene to use for the picking\n * @param ray Ray to use\n * @param predicate Predicate function used to determine eligible meshes and instances. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true. thinInstanceIndex is -1 when the mesh is non-instanced\n * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected\n * @returns an array of PickingInfo\n */\nexport function MultiPickWithRay(scene, ray, predicate, trianglePredicate) {\n return InternalMultiPick(scene, (world) => {\n if (!scene._pickWithRayInverseMatrix) {\n scene._pickWithRayInverseMatrix = Matrix.Identity();\n }\n world.invertToRef(scene._pickWithRayInverseMatrix);\n if (!scene._cachedRayForTransform) {\n scene._cachedRayForTransform = Ray.Zero();\n }\n Ray.TransformToRef(ray, scene._pickWithRayInverseMatrix, scene._cachedRayForTransform);\n return scene._cachedRayForTransform;\n }, predicate, trianglePredicate);\n}\n/**\n * Gets a ray in the forward direction from the camera.\n * @param camera Defines the camera to use to get the ray from\n * @param length Defines the length of the ray to create\n * @param transform Defines the transform to apply to the ray, by default the world matrix is used to create a workd space ray\n * @param origin Defines the start point of the ray which defaults to the camera position\n * @returns the forward ray\n */\nexport function GetForwardRay(camera, length = 100, transform, origin) {\n return GetForwardRayToRef(camera, new Ray(Vector3.Zero(), Vector3.Zero(), length), length, transform, origin);\n}\n/**\n * Gets a ray in the forward direction from the camera.\n * @param camera Defines the camera to use to get the ray from\n * @param refRay the ray to (re)use when setting the values\n * @param length Defines the length of the ray to create\n * @param transform Defines the transform to apply to the ray, by default the world matrx is used to create a workd space ray\n * @param origin Defines the start point of the ray which defaults to the camera position\n * @returns the forward ray\n */\nexport function GetForwardRayToRef(camera, refRay, length = 100, transform, origin) {\n if (!transform) {\n transform = camera.getWorldMatrix();\n }\n refRay.length = length;\n if (origin) {\n refRay.origin.copyFrom(origin);\n }\n else {\n refRay.origin.copyFrom(camera.position);\n }\n const forward = TmpVectors.Vector3[2];\n forward.set(0, 0, camera._scene.useRightHandedSystem ? -1 : 1);\n const worldForward = TmpVectors.Vector3[3];\n Vector3.TransformNormalToRef(forward, transform, worldForward);\n Vector3.NormalizeToRef(worldForward, refRay.direction);\n return refRay;\n}\n/**\n * Initialize the minimal interdependecies between the Ray and Scene and Camera\n * @param sceneClass defines the scene prototype to use\n * @param cameraClass defines the camera prototype to use\n */\nexport function AddRayExtensions(sceneClass, cameraClass) {\n if (cameraClass) {\n cameraClass.prototype.getForwardRay = function (length = 100, transform, origin) {\n return GetForwardRayToRef(this, new Ray(Vector3.Zero(), Vector3.Zero(), length), length, transform, origin);\n };\n cameraClass.prototype.getForwardRayToRef = function (refRay, length = 100, transform, origin) {\n return GetForwardRayToRef(this, refRay, length, transform, origin);\n };\n }\n if (!sceneClass) {\n return;\n }\n _ImportHelper._IsPickingAvailable = true;\n sceneClass.prototype.createPickingRay = function (x, y, world, camera, cameraViewSpace = false) {\n return CreatePickingRay(this, x, y, world, camera, cameraViewSpace);\n };\n}\n"],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}
|