123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- import { Vector3 } from "../Maths/math.vector.js";
- import { CreateLines } from "../Meshes/Builders/linesBuilder.js";
- /**
- * As raycast might be hard to debug, the RayHelper can help rendering the different rays
- * in order to better appreciate the issue one might have.
- * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/interactions/picking_collisions#debugging
- */
- export class RayHelper {
- /**
- * Helper function to create a colored helper in a scene in one line.
- * @param ray Defines the ray we are currently trying to visualize
- * @param scene Defines the scene the ray is used in
- * @param color Defines the color we want to see the ray in
- * @returns The newly created ray helper.
- */
- static CreateAndShow(ray, scene, color) {
- const helper = new RayHelper(ray);
- helper.show(scene, color);
- return helper;
- }
- /**
- * Instantiate a new ray helper.
- * As raycast might be hard to debug, the RayHelper can help rendering the different rays
- * in order to better appreciate the issue one might have.
- * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/interactions/picking_collisions#debugging
- * @param ray Defines the ray we are currently trying to visualize
- */
- constructor(ray) {
- this.ray = ray;
- }
- /**
- * Shows the ray we are willing to debug.
- * @param scene Defines the scene the ray needs to be rendered in
- * @param color Defines the color the ray needs to be rendered in
- */
- show(scene, color) {
- if (!this._renderFunction && this.ray) {
- const ray = this.ray;
- this._renderFunction = () => this._render();
- this._scene = scene;
- this._renderPoints = [ray.origin, ray.origin.add(ray.direction.scale(ray.length))];
- this._renderLine = CreateLines("ray", { points: this._renderPoints, updatable: true }, scene);
- this._renderLine.isPickable = false;
- if (this._renderFunction) {
- this._scene.registerBeforeRender(this._renderFunction);
- }
- }
- if (color && this._renderLine) {
- this._renderLine.color.copyFrom(color);
- }
- }
- /**
- * Hides the ray we are debugging.
- */
- hide() {
- if (this._renderFunction && this._scene) {
- this._scene.unregisterBeforeRender(this._renderFunction);
- this._scene = null;
- this._renderFunction = null;
- if (this._renderLine) {
- this._renderLine.dispose();
- this._renderLine = null;
- }
- this._renderPoints = [];
- }
- }
- _render() {
- const ray = this.ray;
- if (!ray) {
- return;
- }
- const point = this._renderPoints[1];
- const len = Math.min(ray.length, 1000000);
- point.copyFrom(ray.direction);
- point.scaleInPlace(len);
- point.addInPlace(ray.origin);
- this._renderPoints[0].copyFrom(ray.origin);
- CreateLines("ray", { points: this._renderPoints, updatable: true, instance: this._renderLine }, this._scene);
- this._renderLine?.refreshBoundingInfo();
- }
- /**
- * Attach a ray helper to a mesh so that we can easily see its orientation for instance or information like its normals.
- * @param mesh Defines the mesh we want the helper attached to
- * @param meshSpaceDirection Defines the direction of the Ray in mesh space (local space of the mesh node)
- * @param meshSpaceOrigin Defines the origin of the Ray in mesh space (local space of the mesh node)
- * @param length Defines the length of the ray
- */
- attachToMesh(mesh, meshSpaceDirection, meshSpaceOrigin, length) {
- this._attachedToMesh = mesh;
- const ray = this.ray;
- if (!ray) {
- return;
- }
- if (!ray.direction) {
- ray.direction = Vector3.Zero();
- }
- if (!ray.origin) {
- ray.origin = Vector3.Zero();
- }
- if (length) {
- ray.length = length;
- }
- if (!meshSpaceOrigin) {
- meshSpaceOrigin = Vector3.Zero();
- }
- if (!meshSpaceDirection) {
- // -1 so that this will work with Mesh.lookAt
- meshSpaceDirection = new Vector3(0, 0, -1);
- }
- if (!this._scene) {
- this._scene = mesh.getScene();
- }
- if (!this._meshSpaceDirection) {
- this._meshSpaceDirection = meshSpaceDirection.clone();
- this._meshSpaceOrigin = meshSpaceOrigin.clone();
- }
- else {
- this._meshSpaceDirection.copyFrom(meshSpaceDirection);
- this._meshSpaceOrigin.copyFrom(meshSpaceOrigin);
- }
- if (!this._onAfterRenderObserver) {
- this._onAfterRenderObserver = this._scene.onBeforeRenderObservable.add(() => this._updateToMesh());
- this._onAfterStepObserver = this._scene.onAfterStepObservable.add(() => this._updateToMesh());
- }
- // force world matrix computation before the first ray helper computation
- this._attachedToMesh.computeWorldMatrix(true);
- this._updateToMesh();
- }
- /**
- * Detach the ray helper from the mesh it has previously been attached to.
- */
- detachFromMesh() {
- if (this._attachedToMesh && this._scene) {
- if (this._onAfterRenderObserver) {
- this._scene.onBeforeRenderObservable.remove(this._onAfterRenderObserver);
- this._scene.onAfterStepObservable.remove(this._onAfterStepObserver);
- }
- this._attachedToMesh = null;
- this._onAfterRenderObserver = null;
- this._onAfterStepObserver = null;
- this._scene = null;
- }
- }
- _updateToMesh() {
- const ray = this.ray;
- if (!this._attachedToMesh || !ray) {
- return;
- }
- if (this._attachedToMesh.isDisposed()) {
- this.detachFromMesh();
- return;
- }
- this._attachedToMesh.getDirectionToRef(this._meshSpaceDirection, ray.direction);
- Vector3.TransformCoordinatesToRef(this._meshSpaceOrigin, this._attachedToMesh.getWorldMatrix(), ray.origin);
- }
- /**
- * Dispose the helper and release its associated resources.
- */
- dispose() {
- this.hide();
- this.detachFromMesh();
- this.ray = null;
- }
- }
- //# sourceMappingURL=rayHelper.js.map
|