Skip to content

Commit 1111b69

Browse files
authored
Merge pull request #5786 from BabylonJS/ray-disconnect
9k less :) Former-commit-id: bae13109931ce55ed6ce48d98145e11c988bab77
2 parents 0fe7130 + 08bbf4f commit 1111b69

File tree

26 files changed

+341
-255
lines changed

26 files changed

+341
-255
lines changed

src/Audio/sound.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Engine } from "../Engines/engine";
77
import { AbstractMesh } from "../Meshes/abstractMesh";
88
import { TransformNode } from "../Meshes/transformNode";
99
import { Logger } from "../Misc/logger";
10+
import { _DevTools } from '../Misc/devTools';
1011

1112
/**
1213
* Defines a sound that can be played in the application.
@@ -115,7 +116,7 @@ export class Sound {
115116

116117
/** @hidden */
117118
public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {
118-
throw "Import AudioSceneComponent before creating sound.";
119+
throw _DevTools.WarnImport("AudioSceneComponent");
119120
}
120121

121122
/**

src/Cameras/camera.ts

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ import { Matrix, Vector3, Viewport, Plane, Frustum } from "../Maths/math";
99
import { Node } from "../node";
1010
import { Mesh } from "../Meshes/mesh";
1111
import { AbstractMesh } from "../Meshes/abstractMesh";
12-
import { Ray } from "../Culling/ray";
1312
import { ICullable } from "../Culling/boundingInfo";
1413
import { Logger } from "../Misc/logger";
1514
import { _TypeStore } from '../Misc/typeStore';
15+
import { _DevTools } from '../Misc/devTools';
1616

1717
declare type PostProcess = import("../PostProcesses/postProcess").PostProcess;
1818
declare type RenderTargetTexture = import("../Materials/Textures/renderTargetTexture").RenderTargetTexture;
1919
declare type FreeCamera = import("./freeCamera").FreeCamera;
2020
declare type TargetCamera = import("./targetCamera").TargetCamera;
21+
declare type Ray = import("../Culling/ray").Ray;
2122

2223
/**
2324
* This is the base class of all the camera used in the application.
@@ -26,7 +27,7 @@ declare type TargetCamera = import("./targetCamera").TargetCamera;
2627
export class Camera extends Node {
2728
/** @hidden */
2829
public static _createDefaultParsedCamera = (name: string, scene: Scene): Camera => {
29-
throw "UniversalCamera needs to be imported before deserialization can create a default camera.";
30+
throw _DevTools.WarnImport("UniversalCamera");
3031
}
3132

3233
/**
@@ -811,19 +812,7 @@ export class Camera extends Node {
811812
* @returns the forward ray
812813
*/
813814
public getForwardRay(length = 100, transform?: Matrix, origin?: Vector3): Ray {
814-
if (!transform) {
815-
transform = this.getWorldMatrix();
816-
}
817-
818-
if (!origin) {
819-
origin = this.position;
820-
}
821-
var forward = this._scene.useRightHandedSystem ? new Vector3(0, 0, -1) : new Vector3(0, 0, 1);
822-
var forwardWorld = Vector3.TransformNormal(forward, transform);
823-
824-
var direction = Vector3.Normalize(forwardWorld);
825-
826-
return new Ray(origin, direction, length);
815+
throw _DevTools.WarnImport("Ray");
827816
}
828817

829818
/**

src/Collisions/pickingInfo.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { Nullable, FloatArray } from "../types";
22
import { Vector3, Vector2, Tmp } from "../Maths/math";
33
import { AbstractMesh } from "../Meshes/abstractMesh";
44
import { VertexBuffer } from "../Meshes/buffer";
5-
import { Ray } from "../Culling/ray";
65
import { Sprite } from "../Sprites/sprite";
76

7+
declare type Ray = import("../Culling/ray").Ray;
8+
89
/**
910
* Information about the result of picking within a scene
1011
* @see https://doc.babylonjs.com/babylon101/picking_collisions

src/Culling/ray.ts

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { PickingInfo } from "../Collisions/pickingInfo";
66
import { IntersectionInfo } from "../Collisions/intersectionInfo";
77
import { BoundingBox } from "./boundingBox";
88
import { BoundingSphere } from "./boundingSphere";
9+
import { Scene } from '../scene';
10+
import { Camera } from '../Cameras/camera';
911
/**
1012
* Class representing a ray with position and direction
1113
*/
@@ -530,3 +532,234 @@ export class Ray {
530532
this.direction.normalize();
531533
}
532534
}
535+
536+
// Picking
537+
538+
declare module "../scene" {
539+
export interface Scene {
540+
/** @hidden */
541+
_tempPickingRay: Nullable<Ray>;
542+
543+
/** @hidden */
544+
_cachedRayForTransform: Ray;
545+
546+
/** @hidden */
547+
_pickWithRayInverseMatrix: Matrix;
548+
549+
/** @hidden */
550+
_internalPick(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean): Nullable<PickingInfo>;
551+
552+
/** @hidden */
553+
_internalMultiPick(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean): Nullable<PickingInfo[]>;
554+
555+
}
556+
}
557+
558+
Scene.prototype.createPickingRay = function(x: number, y: number, world: Matrix, camera: Nullable<Camera>, cameraViewSpace = false): Ray {
559+
let result = Ray.Zero();
560+
561+
this.createPickingRayToRef(x, y, world, result, camera, cameraViewSpace);
562+
563+
return result;
564+
};
565+
566+
Scene.prototype.createPickingRayToRef = function(x: number, y: number, world: Matrix, result: Ray, camera: Nullable<Camera>, cameraViewSpace = false): Scene {
567+
var engine = this.getEngine();
568+
569+
if (!camera) {
570+
if (!this.activeCamera) {
571+
throw new Error("Active camera not set");
572+
}
573+
574+
camera = this.activeCamera;
575+
}
576+
577+
var cameraViewport = camera.viewport;
578+
var viewport = cameraViewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
579+
580+
// Moving coordinates to local viewport world
581+
x = x / engine.getHardwareScalingLevel() - viewport.x;
582+
y = y / engine.getHardwareScalingLevel() - (engine.getRenderHeight() - viewport.y - viewport.height);
583+
584+
result.update(x, y, viewport.width, viewport.height, world ? world : Matrix.IdentityReadOnly, cameraViewSpace ? Matrix.IdentityReadOnly : camera.getViewMatrix(), camera.getProjectionMatrix());
585+
return this;
586+
};
587+
588+
Scene.prototype.createPickingRayInCameraSpace = function(x: number, y: number, camera?: Camera): Ray {
589+
let result = Ray.Zero();
590+
591+
this.createPickingRayInCameraSpaceToRef(x, y, result, camera);
592+
593+
return result;
594+
};
595+
596+
Scene.prototype.createPickingRayInCameraSpaceToRef = function(x: number, y: number, result: Ray, camera?: Camera): Scene {
597+
if (!PickingInfo) {
598+
return this;
599+
}
600+
601+
var engine = this.getEngine();
602+
603+
if (!camera) {
604+
if (!this.activeCamera) {
605+
throw new Error("Active camera not set");
606+
}
607+
608+
camera = this.activeCamera;
609+
}
610+
611+
var cameraViewport = camera.viewport;
612+
var viewport = cameraViewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
613+
var identity = Matrix.Identity();
614+
615+
// Moving coordinates to local viewport world
616+
x = x / engine.getHardwareScalingLevel() - viewport.x;
617+
y = y / engine.getHardwareScalingLevel() - (engine.getRenderHeight() - viewport.y - viewport.height);
618+
result.update(x, y, viewport.width, viewport.height, identity, identity, camera.getProjectionMatrix());
619+
return this;
620+
};
621+
622+
Scene.prototype._internalPick = function(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean): Nullable<PickingInfo> {
623+
if (!PickingInfo) {
624+
return null;
625+
}
626+
627+
var pickingInfo = null;
628+
629+
for (var meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
630+
var mesh = this.meshes[meshIndex];
631+
632+
if (predicate) {
633+
if (!predicate(mesh)) {
634+
continue;
635+
}
636+
} else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
637+
continue;
638+
}
639+
640+
var world = mesh.getWorldMatrix();
641+
var ray = rayFunction(world);
642+
643+
var result = mesh.intersects(ray, fastCheck);
644+
if (!result || !result.hit) {
645+
continue;
646+
}
647+
648+
if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance) {
649+
continue;
650+
}
651+
652+
pickingInfo = result;
653+
654+
if (fastCheck) {
655+
break;
656+
}
657+
}
658+
659+
return pickingInfo || new PickingInfo();
660+
};
661+
662+
Scene.prototype._internalMultiPick = function(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean): Nullable<PickingInfo[]> {
663+
if (!PickingInfo) {
664+
return null;
665+
}
666+
var pickingInfos = new Array<PickingInfo>();
667+
668+
for (var meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
669+
var mesh = this.meshes[meshIndex];
670+
671+
if (predicate) {
672+
if (!predicate(mesh)) {
673+
continue;
674+
}
675+
} else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
676+
continue;
677+
}
678+
679+
var world = mesh.getWorldMatrix();
680+
var ray = rayFunction(world);
681+
682+
var result = mesh.intersects(ray, false);
683+
if (!result || !result.hit) {
684+
continue;
685+
}
686+
687+
pickingInfos.push(result);
688+
}
689+
690+
return pickingInfos;
691+
};
692+
693+
Scene.prototype.pick = function(x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean, camera?: Nullable<Camera>): Nullable<PickingInfo> {
694+
if (!PickingInfo) {
695+
return null;
696+
}
697+
var result = this._internalPick((world) => {
698+
if (!this._tempPickingRay) {
699+
this._tempPickingRay = Ray.Zero();
700+
}
701+
702+
this.createPickingRayToRef(x, y, world, this._tempPickingRay, camera || null);
703+
return this._tempPickingRay;
704+
}, predicate, fastCheck);
705+
if (result) {
706+
result.ray = this.createPickingRay(x, y, Matrix.Identity(), camera || null);
707+
}
708+
return result;
709+
};
710+
711+
Scene.prototype.pickWithRay = function(ray: Ray, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean): Nullable<PickingInfo> {
712+
var result = this._internalPick((world) => {
713+
if (!this._pickWithRayInverseMatrix) {
714+
this._pickWithRayInverseMatrix = Matrix.Identity();
715+
}
716+
world.invertToRef(this._pickWithRayInverseMatrix);
717+
718+
if (!this._cachedRayForTransform) {
719+
this._cachedRayForTransform = Ray.Zero();
720+
}
721+
722+
Ray.TransformToRef(ray, this._pickWithRayInverseMatrix, this._cachedRayForTransform);
723+
return this._cachedRayForTransform;
724+
}, predicate, fastCheck);
725+
if (result) {
726+
result.ray = ray;
727+
}
728+
return result;
729+
};
730+
731+
Scene.prototype.multiPick = function(x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean, camera?: Camera): Nullable<PickingInfo[]> {
732+
return this._internalMultiPick((world) => this.createPickingRay(x, y, world, camera || null), predicate);
733+
};
734+
735+
Scene.prototype.multiPickWithRay = function(ray: Ray, predicate: (mesh: AbstractMesh) => boolean): Nullable<PickingInfo[]> {
736+
return this._internalMultiPick((world) => {
737+
if (!this._pickWithRayInverseMatrix) {
738+
this._pickWithRayInverseMatrix = Matrix.Identity();
739+
}
740+
world.invertToRef(this._pickWithRayInverseMatrix);
741+
742+
if (!this._cachedRayForTransform) {
743+
this._cachedRayForTransform = Ray.Zero();
744+
}
745+
746+
Ray.TransformToRef(ray, this._pickWithRayInverseMatrix, this._cachedRayForTransform);
747+
return this._cachedRayForTransform;
748+
}, predicate);
749+
};
750+
751+
Camera.prototype.getForwardRay = function(length = 100, transform?: Matrix, origin?: Vector3): Ray {
752+
if (!transform) {
753+
transform = this.getWorldMatrix();
754+
}
755+
756+
if (!origin) {
757+
origin = this.position;
758+
}
759+
var forward = this._scene.useRightHandedSystem ? new Vector3(0, 0, -1) : new Vector3(0, 0, 1);
760+
var forwardWorld = Vector3.TransformNormal(forward, transform);
761+
762+
var direction = Vector3.Normalize(forwardWorld);
763+
764+
return new Ray(origin, direction, length);
765+
};

src/Engines/engine.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { DomManagement } from "../Misc/domManagement";
2828
import { Logger } from "../Misc/logger";
2929
import { EngineStore } from "./engineStore";
3030
import { RenderTargetCreationOptions } from "../Materials/Textures/renderTargetCreationOptions";
31+
import { _DevTools } from '../Misc/devTools';
3132

3233
declare type PostProcess = import("../PostProcesses/postProcess").PostProcess;
3334
declare type Texture = import("../Materials/Textures/texture").Texture;
@@ -530,7 +531,7 @@ export class Engine {
530531
* @returns The loading screen
531532
*/
532533
public static DefaultLoadingScreenFactory(canvas: HTMLCanvasElement): ILoadingScreen {
533-
throw "Import LoadingScreen or set DefaultLoadingScreenFactory on engine before using the loading screen";
534+
throw _DevTools.WarnImport("LoadingScreen");
534535
}
535536

536537
/**

src/Events/pointerEvents.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { Nullable } from "../types";
22
import { Vector2 } from "../Maths/math";
33
import { PickingInfo } from "../Collisions/pickingInfo";
4-
import { Ray } from "../Culling/ray";
54
import { _TimeToken } from "../Instrumentation/timeToken";
65
import { _DepthCullingState, _StencilState, _AlphaState } from "../States/index";
6+
7+
declare type Ray = import("../Culling/ray").Ray;
8+
79
/**
810
* Gather the list of pointer event types as constants.
911
*/

src/Layers/effectLayer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { Constants } from "../Engines/constants";
2525

2626
import "../Shaders/glowMapGeneration.fragment";
2727
import "../Shaders/glowMapGeneration.vertex";
28+
import { _DevTools } from '../Misc/devTools';
2829

2930
/**
3031
* Effect layer options. This helps customizing the behaviour
@@ -146,7 +147,7 @@ export abstract class EffectLayer {
146147

147148
/** @hidden */
148149
public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {
149-
throw "Import EffectLayerSceneComponent before creating EffectLayer.";
150+
throw _DevTools.WarnImport("EffectLayerSceneComponent");
150151
}
151152

152153
/**

src/LensFlares/lensFlareSystem.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { Constants } from "../Engines/constants";
1616

1717
import "../Shaders/lensFlare.fragment";
1818
import "../Shaders/lensFlare.vertex";
19+
import { _DevTools } from '../Misc/devTools';
1920

2021
/**
2122
* This represents a Lens Flare System or the shiny effect created by the light reflection on the camera lenses.
@@ -65,7 +66,7 @@ export class LensFlareSystem {
6566

6667
/** @hidden */
6768
public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {
68-
throw "Import LensFlareSystemSceneComponent before creating LensFlareSystem.";
69+
throw _DevTools.WarnImport("LensFlareSystemSceneComponent");
6970
}
7071

7172
/**

0 commit comments

Comments
 (0)