Skip to content

Commit

Permalink
Merge pull request #5786 from BabylonJS/ray-disconnect
Browse files Browse the repository at this point in the history
9k less :)
  • Loading branch information
sebavan committed Jan 17, 2019
2 parents c61f206 + 68ba14b commit 94ca2b6
Show file tree
Hide file tree
Showing 26 changed files with 341 additions and 255 deletions.
3 changes: 2 additions & 1 deletion src/Audio/sound.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Engine } from "../Engines/engine";
import { AbstractMesh } from "../Meshes/abstractMesh";
import { TransformNode } from "../Meshes/transformNode";
import { Logger } from "../Misc/logger";
import { _DevTools } from '../Misc/devTools';

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

/** @hidden */
public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {
throw "Import AudioSceneComponent before creating sound.";
throw _DevTools.WarnImport("AudioSceneComponent");
}

/**
Expand Down
19 changes: 4 additions & 15 deletions src/Cameras/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import { Matrix, Vector3, Viewport, Plane, Frustum } from "../Maths/math";
import { Node } from "../node";
import { Mesh } from "../Meshes/mesh";
import { AbstractMesh } from "../Meshes/abstractMesh";
import { Ray } from "../Culling/ray";
import { ICullable } from "../Culling/boundingInfo";
import { Logger } from "../Misc/logger";
import { _TypeStore } from '../Misc/typeStore';
import { _DevTools } from '../Misc/devTools';

declare type PostProcess = import("../PostProcesses/postProcess").PostProcess;
declare type RenderTargetTexture = import("../Materials/Textures/renderTargetTexture").RenderTargetTexture;
declare type FreeCamera = import("./freeCamera").FreeCamera;
declare type TargetCamera = import("./targetCamera").TargetCamera;
declare type Ray = import("../Culling/ray").Ray;

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

/**
Expand Down Expand Up @@ -811,19 +812,7 @@ export class Camera extends Node {
* @returns the forward ray
*/
public getForwardRay(length = 100, transform?: Matrix, origin?: Vector3): Ray {
if (!transform) {
transform = this.getWorldMatrix();
}

if (!origin) {
origin = this.position;
}
var forward = this._scene.useRightHandedSystem ? new Vector3(0, 0, -1) : new Vector3(0, 0, 1);
var forwardWorld = Vector3.TransformNormal(forward, transform);

var direction = Vector3.Normalize(forwardWorld);

return new Ray(origin, direction, length);
throw _DevTools.WarnImport("Ray");
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/Collisions/pickingInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { Nullable, FloatArray } from "../types";
import { Vector3, Vector2, Tmp } from "../Maths/math";
import { AbstractMesh } from "../Meshes/abstractMesh";
import { VertexBuffer } from "../Meshes/buffer";
import { Ray } from "../Culling/ray";
import { Sprite } from "../Sprites/sprite";

declare type Ray = import("../Culling/ray").Ray;

/**
* Information about the result of picking within a scene
* @see https://doc.babylonjs.com/babylon101/picking_collisions
Expand Down
233 changes: 233 additions & 0 deletions src/Culling/ray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { PickingInfo } from "../Collisions/pickingInfo";
import { IntersectionInfo } from "../Collisions/intersectionInfo";
import { BoundingBox } from "./boundingBox";
import { BoundingSphere } from "./boundingSphere";
import { Scene } from '../scene';
import { Camera } from '../Cameras/camera';
/**
* Class representing a ray with position and direction
*/
Expand Down Expand Up @@ -530,3 +532,234 @@ export class Ray {
this.direction.normalize();
}
}

// Picking

declare module "../scene" {
export interface Scene {
/** @hidden */
_tempPickingRay: Nullable<Ray>;

/** @hidden */
_cachedRayForTransform: Ray;

/** @hidden */
_pickWithRayInverseMatrix: Matrix;

/** @hidden */
_internalPick(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean): Nullable<PickingInfo>;

/** @hidden */
_internalMultiPick(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean): Nullable<PickingInfo[]>;

}
}

Scene.prototype.createPickingRay = function(x: number, y: number, world: Matrix, camera: Nullable<Camera>, cameraViewSpace = false): Ray {
let result = Ray.Zero();

this.createPickingRayToRef(x, y, world, result, camera, cameraViewSpace);

return result;
};

Scene.prototype.createPickingRayToRef = function(x: number, y: number, world: Matrix, result: Ray, camera: Nullable<Camera>, cameraViewSpace = false): Scene {
var engine = this.getEngine();

if (!camera) {
if (!this.activeCamera) {
throw new Error("Active camera not set");
}

camera = this.activeCamera;
}

var cameraViewport = camera.viewport;
var viewport = cameraViewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());

// Moving coordinates to local viewport world
x = x / engine.getHardwareScalingLevel() - viewport.x;
y = y / engine.getHardwareScalingLevel() - (engine.getRenderHeight() - viewport.y - viewport.height);

result.update(x, y, viewport.width, viewport.height, world ? world : Matrix.IdentityReadOnly, cameraViewSpace ? Matrix.IdentityReadOnly : camera.getViewMatrix(), camera.getProjectionMatrix());
return this;
};

Scene.prototype.createPickingRayInCameraSpace = function(x: number, y: number, camera?: Camera): Ray {
let result = Ray.Zero();

this.createPickingRayInCameraSpaceToRef(x, y, result, camera);

return result;
};

Scene.prototype.createPickingRayInCameraSpaceToRef = function(x: number, y: number, result: Ray, camera?: Camera): Scene {
if (!PickingInfo) {
return this;
}

var engine = this.getEngine();

if (!camera) {
if (!this.activeCamera) {
throw new Error("Active camera not set");
}

camera = this.activeCamera;
}

var cameraViewport = camera.viewport;
var viewport = cameraViewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
var identity = Matrix.Identity();

// Moving coordinates to local viewport world
x = x / engine.getHardwareScalingLevel() - viewport.x;
y = y / engine.getHardwareScalingLevel() - (engine.getRenderHeight() - viewport.y - viewport.height);
result.update(x, y, viewport.width, viewport.height, identity, identity, camera.getProjectionMatrix());
return this;
};

Scene.prototype._internalPick = function(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean): Nullable<PickingInfo> {
if (!PickingInfo) {
return null;
}

var pickingInfo = null;

for (var meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
var mesh = this.meshes[meshIndex];

if (predicate) {
if (!predicate(mesh)) {
continue;
}
} else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
continue;
}

var world = mesh.getWorldMatrix();
var ray = rayFunction(world);

var result = mesh.intersects(ray, fastCheck);
if (!result || !result.hit) {
continue;
}

if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance) {
continue;
}

pickingInfo = result;

if (fastCheck) {
break;
}
}

return pickingInfo || new PickingInfo();
};

Scene.prototype._internalMultiPick = function(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean): Nullable<PickingInfo[]> {
if (!PickingInfo) {
return null;
}
var pickingInfos = new Array<PickingInfo>();

for (var meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
var mesh = this.meshes[meshIndex];

if (predicate) {
if (!predicate(mesh)) {
continue;
}
} else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
continue;
}

var world = mesh.getWorldMatrix();
var ray = rayFunction(world);

var result = mesh.intersects(ray, false);
if (!result || !result.hit) {
continue;
}

pickingInfos.push(result);
}

return pickingInfos;
};

Scene.prototype.pick = function(x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean, camera?: Nullable<Camera>): Nullable<PickingInfo> {
if (!PickingInfo) {
return null;
}
var result = this._internalPick((world) => {
if (!this._tempPickingRay) {
this._tempPickingRay = Ray.Zero();
}

this.createPickingRayToRef(x, y, world, this._tempPickingRay, camera || null);
return this._tempPickingRay;
}, predicate, fastCheck);
if (result) {
result.ray = this.createPickingRay(x, y, Matrix.Identity(), camera || null);
}
return result;
};

Scene.prototype.pickWithRay = function(ray: Ray, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean): Nullable<PickingInfo> {
var result = this._internalPick((world) => {
if (!this._pickWithRayInverseMatrix) {
this._pickWithRayInverseMatrix = Matrix.Identity();
}
world.invertToRef(this._pickWithRayInverseMatrix);

if (!this._cachedRayForTransform) {
this._cachedRayForTransform = Ray.Zero();
}

Ray.TransformToRef(ray, this._pickWithRayInverseMatrix, this._cachedRayForTransform);
return this._cachedRayForTransform;
}, predicate, fastCheck);
if (result) {
result.ray = ray;
}
return result;
};

Scene.prototype.multiPick = function(x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean, camera?: Camera): Nullable<PickingInfo[]> {
return this._internalMultiPick((world) => this.createPickingRay(x, y, world, camera || null), predicate);
};

Scene.prototype.multiPickWithRay = function(ray: Ray, predicate: (mesh: AbstractMesh) => boolean): Nullable<PickingInfo[]> {
return this._internalMultiPick((world) => {
if (!this._pickWithRayInverseMatrix) {
this._pickWithRayInverseMatrix = Matrix.Identity();
}
world.invertToRef(this._pickWithRayInverseMatrix);

if (!this._cachedRayForTransform) {
this._cachedRayForTransform = Ray.Zero();
}

Ray.TransformToRef(ray, this._pickWithRayInverseMatrix, this._cachedRayForTransform);
return this._cachedRayForTransform;
}, predicate);
};

Camera.prototype.getForwardRay = function(length = 100, transform?: Matrix, origin?: Vector3): Ray {
if (!transform) {
transform = this.getWorldMatrix();
}

if (!origin) {
origin = this.position;
}
var forward = this._scene.useRightHandedSystem ? new Vector3(0, 0, -1) : new Vector3(0, 0, 1);
var forwardWorld = Vector3.TransformNormal(forward, transform);

var direction = Vector3.Normalize(forwardWorld);

return new Ray(origin, direction, length);
};
3 changes: 2 additions & 1 deletion src/Engines/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { DomManagement } from "../Misc/domManagement";
import { Logger } from "../Misc/logger";
import { EngineStore } from "./engineStore";
import { RenderTargetCreationOptions } from "../Materials/Textures/renderTargetCreationOptions";
import { _DevTools } from '../Misc/devTools';

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

/**
Expand Down
4 changes: 3 additions & 1 deletion src/Events/pointerEvents.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Nullable } from "../types";
import { Vector2 } from "../Maths/math";
import { PickingInfo } from "../Collisions/pickingInfo";
import { Ray } from "../Culling/ray";
import { _TimeToken } from "../Instrumentation/timeToken";
import { _DepthCullingState, _StencilState, _AlphaState } from "../States/index";

declare type Ray = import("../Culling/ray").Ray;

/**
* Gather the list of pointer event types as constants.
*/
Expand Down
3 changes: 2 additions & 1 deletion src/Layers/effectLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { Constants } from "../Engines/constants";

import "../Shaders/glowMapGeneration.fragment";
import "../Shaders/glowMapGeneration.vertex";
import { _DevTools } from '../Misc/devTools';

/**
* Effect layer options. This helps customizing the behaviour
Expand Down Expand Up @@ -146,7 +147,7 @@ export abstract class EffectLayer {

/** @hidden */
public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {
throw "Import EffectLayerSceneComponent before creating EffectLayer.";
throw _DevTools.WarnImport("EffectLayerSceneComponent");
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/LensFlares/lensFlareSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Constants } from "../Engines/constants";

import "../Shaders/lensFlare.fragment";
import "../Shaders/lensFlare.vertex";
import { _DevTools } from '../Misc/devTools';

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

/** @hidden */
public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {
throw "Import LensFlareSystemSceneComponent before creating LensFlareSystem.";
throw _DevTools.WarnImport("LensFlareSystemSceneComponent");
}

/**
Expand Down
Loading

0 comments on commit 94ca2b6

Please sign in to comment.