import type { DeepImmutable, Nullable, float } from "../types"; import { Matrix, Vector3 } from "../Maths/math.vector"; import type { AbstractMesh } from "../Meshes/abstractMesh"; import { PickingInfo } from "../Collisions/pickingInfo"; import { IntersectionInfo } from "../Collisions/intersectionInfo"; import type { BoundingBox } from "./boundingBox"; import type { BoundingSphere } from "./boundingSphere"; import type { Plane } from "../Maths/math.plane"; /** * Class representing a ray with position and direction */ export declare class Ray { /** origin point */ origin: Vector3; /** direction */ direction: Vector3; /** length of the ray */ length: number; /** The epsilon value to use when calculating the ray/triangle intersection (default: Epsilon from math constants) */ epsilon: number; private static readonly _TmpVector3; private static _RayDistant; private _tmpRay; /** * Creates a new ray * @param origin origin point * @param direction direction * @param length length of the ray * @param epsilon The epsilon value to use when calculating the ray/triangle intersection (default: 0) */ constructor( /** origin point */ origin: Vector3, /** direction */ direction: Vector3, /** length of the ray */ length?: number, /** The epsilon value to use when calculating the ray/triangle intersection (default: Epsilon from math constants) */ epsilon?: number); /** * Clone the current ray * @returns a new ray */ clone(): Ray; /** * Checks if the ray intersects a box * This does not account for the ray length by design to improve perfs. * @param minimum bound of the box * @param maximum bound of the box * @param intersectionTreshold extra extend to be added to the box in all direction * @returns if the box was hit */ intersectsBoxMinMax(minimum: DeepImmutable, maximum: DeepImmutable, intersectionTreshold?: number): boolean; /** * Checks if the ray intersects a box * This does not account for the ray lenght by design to improve perfs. * @param box the bounding box to check * @param intersectionTreshold extra extend to be added to the BoundingBox in all direction * @returns if the box was hit */ intersectsBox(box: DeepImmutable, intersectionTreshold?: number): boolean; /** * If the ray hits a sphere * @param sphere the bounding sphere to check * @param intersectionTreshold extra extend to be added to the BoundingSphere in all direction * @returns true if it hits the sphere */ intersectsSphere(sphere: DeepImmutable, intersectionTreshold?: number): boolean; /** * If the ray hits a triange * @param vertex0 triangle vertex * @param vertex1 triangle vertex * @param vertex2 triangle vertex * @returns intersection information if hit */ intersectsTriangle(vertex0: DeepImmutable, vertex1: DeepImmutable, vertex2: DeepImmutable): Nullable; /** * Checks if ray intersects a plane * @param plane the plane to check * @returns the distance away it was hit */ intersectsPlane(plane: DeepImmutable): Nullable; /** * Calculate the intercept of a ray on a given axis * @param axis to check 'x' | 'y' | 'z' * @param offset from axis interception (i.e. an offset of 1y is intercepted above ground) * @returns a vector containing the coordinates where 'axis' is equal to zero (else offset), or null if there is no intercept. */ intersectsAxis(axis: string, offset?: number): Nullable; /** * 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, * irrespective of orientation. * @param mesh the mesh to check * @param fastCheck defines if the first intersection will be used (and not the closest) * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected * @param onlyBoundingInfo defines a boolean indicating if picking should only happen using bounding info (false by default) * @param worldToUse defines the world matrix to use to get the world coordinate of the intersection point * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check * @returns picking info of the intersection */ intersectsMesh(mesh: DeepImmutable, fastCheck?: boolean, trianglePredicate?: TrianglePickingPredicate, onlyBoundingInfo?: boolean, worldToUse?: Matrix, skipBoundingInfo?: boolean): PickingInfo; /** * Checks if ray intersects a mesh * @param meshes the meshes to check * @param fastCheck defines if the first intersection will be used (and not the closest) * @param results array to store result in * @returns Array of picking infos */ intersectsMeshes(meshes: Array>, fastCheck?: boolean, results?: Array): Array; private _comparePickingInfo; private static _Smallnum; private static _Rayl; /** * Intersection test between the ray and a given segment within a given tolerance (threshold) * @param sega the first point of the segment to test the intersection against * @param segb the second point of the segment to test the intersection against * @param threshold the tolerance margin, if the ray doesn't intersect the segment but is close to the given threshold, the intersection is successful * @returns the distance from the ray origin to the intersection point if there's intersection, or -1 if there's no intersection */ intersectionSegment(sega: DeepImmutable, segb: DeepImmutable, threshold: number): number; /** * Update the ray from viewport position * @param x position * @param y y position * @param viewportWidth viewport width * @param viewportHeight viewport height * @param world world matrix * @param view view matrix * @param projection projection matrix * @param enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default) * @returns this ray updated */ update(x: number, y: number, viewportWidth: number, viewportHeight: number, world: DeepImmutable, view: DeepImmutable, projection: DeepImmutable, enableDistantPicking?: boolean): Ray; /** * Creates a ray with origin and direction of 0,0,0 * @returns the new ray */ static Zero(): Ray; /** * Creates a new ray from screen space and viewport * @param x position * @param y y position * @param viewportWidth viewport width * @param viewportHeight viewport height * @param world world matrix * @param view view matrix * @param projection projection matrix * @returns new ray */ static CreateNew(x: number, y: number, viewportWidth: number, viewportHeight: number, world: DeepImmutable, view: DeepImmutable, projection: DeepImmutable): Ray; /** * 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 * transformed to the given world matrix. * @param origin The origin point * @param end The end point * @param world a matrix to transform the ray to. Default is the identity matrix. * @returns the new ray */ static CreateNewFromTo(origin: Vector3, end: Vector3, world?: DeepImmutable): Ray; /** * 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 * transformed to the given world matrix. * @param origin The origin point * @param end The end point * @param result the object to store the result * @param world a matrix to transform the ray to. Default is the identity matrix. * @returns the ref ray */ static CreateFromToToRef(origin: Vector3, end: Vector3, result: Ray, world?: DeepImmutable): Ray; /** * Transforms a ray by a matrix * @param ray ray to transform * @param matrix matrix to apply * @returns the resulting new ray */ static Transform(ray: DeepImmutable, matrix: DeepImmutable): Ray; /** * Transforms a ray by a matrix * @param ray ray to transform * @param matrix matrix to apply * @param result ray to store result in * @returns the updated result ray */ static TransformToRef(ray: DeepImmutable, matrix: DeepImmutable, result: Ray): Ray; /** * Unproject a ray from screen space to object space * @param sourceX defines the screen space x coordinate to use * @param sourceY defines the screen space y coordinate to use * @param viewportWidth defines the current width of the viewport * @param viewportHeight defines the current height of the viewport * @param world defines the world matrix to use (can be set to Identity to go to world space) * @param view defines the view matrix to use * @param projection defines the projection matrix to use */ unprojectRayToRef(sourceX: float, sourceY: float, viewportWidth: number, viewportHeight: number, world: DeepImmutable, view: DeepImmutable, projection: DeepImmutable): void; } /** * Type used to define predicate used to select faces when a mesh intersection is detected */ export type TrianglePickingPredicate = (p0: Vector3, p1: Vector3, p2: Vector3, ray: Ray, i0: number, i1: number, i2: number) => boolean; declare module "../scene" { interface Scene { /** @internal */ _tempPickingRay: Nullable; /** @internal */ _cachedRayForTransform: Ray; /** @internal */ _pickWithRayInverseMatrix: Matrix; /** @internal */ _internalPick(rayFunction: (world: Matrix, enableDistantPicking: boolean) => Ray, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean, onlyBoundingInfo?: boolean, trianglePredicate?: TrianglePickingPredicate): PickingInfo; /** @internal */ _internalMultiPick(rayFunction: (world: Matrix, enableDistantPicking: boolean) => Ray, predicate?: (mesh: AbstractMesh) => boolean, trianglePredicate?: TrianglePickingPredicate): Nullable; /** @internal */ _internalPickForMesh(pickingInfo: Nullable, rayFunction: (world: Matrix, enableDistantPicking: boolean) => Ray, mesh: AbstractMesh, world: Matrix, fastCheck?: boolean, onlyBoundingInfo?: boolean, trianglePredicate?: TrianglePickingPredicate, skipBoundingInfo?: boolean): Nullable; } }