|
@@ -6,9 +6,9 @@ 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';
|
|
|
-import { Plane } from '../Maths/math.plane';
|
|
|
+import { Scene } from "../scene";
|
|
|
+import { Camera } from "../Cameras/camera";
|
|
|
+import { Plane } from "../Maths/math.plane";
|
|
|
/**
|
|
|
* Class representing a ray with position and direction
|
|
|
*/
|
|
@@ -28,8 +28,8 @@ export class Ray {
|
|
|
/** direction */
|
|
|
public direction: Vector3,
|
|
|
/** length of the ray */
|
|
|
- public length: number = Number.MAX_VALUE) {
|
|
|
- }
|
|
|
+ public length: number = Number.MAX_VALUE
|
|
|
+ ) {}
|
|
|
|
|
|
// Methods
|
|
|
/**
|
|
@@ -53,8 +53,7 @@ export class Ray {
|
|
|
if (this.origin.x < newMinimum.x || this.origin.x > newMaximum.x) {
|
|
|
return false;
|
|
|
}
|
|
|
- }
|
|
|
- else {
|
|
|
+ } else {
|
|
|
inv = 1.0 / this.direction.x;
|
|
|
min = (newMinimum.x - this.origin.x) * inv;
|
|
|
max = (newMaximum.x - this.origin.x) * inv;
|
|
@@ -80,8 +79,7 @@ export class Ray {
|
|
|
if (this.origin.y < newMinimum.y || this.origin.y > newMaximum.y) {
|
|
|
return false;
|
|
|
}
|
|
|
- }
|
|
|
- else {
|
|
|
+ } else {
|
|
|
inv = 1.0 / this.direction.y;
|
|
|
min = (newMinimum.y - this.origin.y) * inv;
|
|
|
max = (newMaximum.y - this.origin.y) * inv;
|
|
@@ -108,8 +106,7 @@ export class Ray {
|
|
|
if (this.origin.z < newMinimum.z || this.origin.z > newMaximum.z) {
|
|
|
return false;
|
|
|
}
|
|
|
- }
|
|
|
- else {
|
|
|
+ } else {
|
|
|
inv = 1.0 / this.direction.z;
|
|
|
min = (newMinimum.z - this.origin.z) * inv;
|
|
|
max = (newMaximum.z - this.origin.z) * inv;
|
|
@@ -155,7 +152,7 @@ export class Ray {
|
|
|
var x = sphere.center.x - this.origin.x;
|
|
|
var y = sphere.center.y - this.origin.y;
|
|
|
var z = sphere.center.z - this.origin.z;
|
|
|
- var pyth = (x * x) + (y * y) + (z * z);
|
|
|
+ var pyth = x * x + y * y + z * z;
|
|
|
const radius = sphere.radius + intersectionTreshold;
|
|
|
var rr = radius * radius;
|
|
|
|
|
@@ -163,12 +160,12 @@ export class Ray {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- var dot = (x * this.direction.x) + (y * this.direction.y) + (z * this.direction.z);
|
|
|
+ var dot = x * this.direction.x + y * this.direction.y + z * this.direction.z;
|
|
|
if (dot < 0.0) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- var temp = pyth - (dot * dot);
|
|
|
+ var temp = pyth - dot * dot;
|
|
|
|
|
|
return temp <= rr;
|
|
|
}
|
|
@@ -231,14 +228,13 @@ export class Ray {
|
|
|
public intersectsPlane(plane: DeepImmutable<Plane>): Nullable<number> {
|
|
|
var distance: number;
|
|
|
var result1 = Vector3.Dot(plane.normal, this.direction);
|
|
|
- if (Math.abs(result1) < 9.99999997475243E-07) {
|
|
|
+ if (Math.abs(result1) < 9.99999997475243e-7) {
|
|
|
return null;
|
|
|
- }
|
|
|
- else {
|
|
|
+ } else {
|
|
|
var result2 = Vector3.Dot(plane.normal, this.origin);
|
|
|
distance = (-plane.d - result2) / result1;
|
|
|
if (distance < 0.0) {
|
|
|
- if (distance < -9.99999997475243E-07) {
|
|
|
+ if (distance < -9.99999997475243e-7) {
|
|
|
return null;
|
|
|
} else {
|
|
|
return 0;
|
|
@@ -256,24 +252,24 @@ export class Ray {
|
|
|
*/
|
|
|
public intersectsAxis(axis: string, offset: number = 0): Nullable<Vector3> {
|
|
|
switch (axis) {
|
|
|
- case 'y':
|
|
|
+ case "y":
|
|
|
var t = (this.origin.y - offset) / this.direction.y;
|
|
|
if (t > 0) {
|
|
|
return null;
|
|
|
}
|
|
|
- return new Vector3(this.origin.x + (this.direction.x * -t), offset, this.origin.z + (this.direction.z * -t));
|
|
|
- case 'x':
|
|
|
+ return new Vector3(this.origin.x + this.direction.x * -t, offset, this.origin.z + this.direction.z * -t);
|
|
|
+ case "x":
|
|
|
var t = (this.origin.x - offset) / this.direction.x;
|
|
|
if (t > 0) {
|
|
|
return null;
|
|
|
}
|
|
|
- return new Vector3(offset, this.origin.y + (this.direction.y * -t), this.origin.z + (this.direction.z * -t));
|
|
|
- case 'z':
|
|
|
+ return new Vector3(offset, this.origin.y + this.direction.y * -t, this.origin.z + this.direction.z * -t);
|
|
|
+ case "z":
|
|
|
var t = (this.origin.z - offset) / this.direction.z;
|
|
|
if (t > 0) {
|
|
|
return null;
|
|
|
}
|
|
|
- return new Vector3(this.origin.x + (this.direction.x * -t), this.origin.y + (this.direction.y * -t), offset);
|
|
|
+ return new Vector3(this.origin.x + this.direction.x * -t, this.origin.y + this.direction.y * -t, offset);
|
|
|
default:
|
|
|
return null;
|
|
|
}
|
|
@@ -286,7 +282,6 @@ export class Ray {
|
|
|
* @returns picking info of the intersecton
|
|
|
*/
|
|
|
public intersectsMesh(mesh: DeepImmutable<AbstractMesh>, fastCheck?: boolean): PickingInfo {
|
|
|
-
|
|
|
var tm = TmpVectors.Matrix[0];
|
|
|
|
|
|
mesh.getWorldMatrix().invertToRef(tm);
|
|
@@ -298,7 +293,6 @@ export class Ray {
|
|
|
}
|
|
|
|
|
|
return mesh.intersects(this._tmpRay, fastCheck);
|
|
|
-
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -309,7 +303,6 @@ export class Ray {
|
|
|
* @returns Array of picking infos
|
|
|
*/
|
|
|
public intersectsMeshes(meshes: Array<DeepImmutable<AbstractMesh>>, fastCheck?: boolean, results?: Array<PickingInfo>): Array<PickingInfo> {
|
|
|
-
|
|
|
if (results) {
|
|
|
results.length = 0;
|
|
|
} else {
|
|
@@ -327,11 +320,9 @@ export class Ray {
|
|
|
results.sort(this._comparePickingInfo);
|
|
|
|
|
|
return results;
|
|
|
-
|
|
|
}
|
|
|
|
|
|
private _comparePickingInfo(pickingInfoA: DeepImmutable<PickingInfo>, pickingInfoB: DeepImmutable<PickingInfo>): number {
|
|
|
-
|
|
|
if (pickingInfoA.distance < pickingInfoB.distance) {
|
|
|
return -1;
|
|
|
} else if (pickingInfoA.distance > pickingInfoB.distance) {
|
|
@@ -339,7 +330,6 @@ export class Ray {
|
|
|
} else {
|
|
|
return 0;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
private static smallnum = 0.00000001;
|
|
@@ -366,63 +356,71 @@ export class Ray {
|
|
|
|
|
|
sega.subtractToRef(o, w);
|
|
|
|
|
|
- var a = Vector3.Dot(u, u); // always >= 0
|
|
|
+ var a = Vector3.Dot(u, u); // always >= 0
|
|
|
var b = Vector3.Dot(u, v);
|
|
|
- var c = Vector3.Dot(v, v); // always >= 0
|
|
|
+ var c = Vector3.Dot(v, v); // always >= 0
|
|
|
var d = Vector3.Dot(u, w);
|
|
|
var e = Vector3.Dot(v, w);
|
|
|
- var D = a * c - b * b; // always >= 0
|
|
|
- var sc: number, sN: number, sD = D; // sc = sN / sD, default sD = D >= 0
|
|
|
- var tc: number, tN: number, tD = D; // tc = tN / tD, default tD = D >= 0
|
|
|
+ var D = a * c - b * b; // always >= 0
|
|
|
+ var sc: number,
|
|
|
+ sN: number,
|
|
|
+ sD = D; // sc = sN / sD, default sD = D >= 0
|
|
|
+ var tc: number,
|
|
|
+ tN: number,
|
|
|
+ tD = D; // tc = tN / tD, default tD = D >= 0
|
|
|
|
|
|
// compute the line parameters of the two closest points
|
|
|
- if (D < Ray.smallnum) { // the lines are almost parallel
|
|
|
- sN = 0.0; // force using point P0 on segment S1
|
|
|
- sD = 1.0; // to prevent possible division by 0.0 later
|
|
|
+ if (D < Ray.smallnum) {
|
|
|
+ // the lines are almost parallel
|
|
|
+ sN = 0.0; // force using point P0 on segment S1
|
|
|
+ sD = 1.0; // to prevent possible division by 0.0 later
|
|
|
tN = e;
|
|
|
tD = c;
|
|
|
- }
|
|
|
- else { // get the closest points on the infinite lines
|
|
|
- sN = (b * e - c * d);
|
|
|
- tN = (a * e - b * d);
|
|
|
- if (sN < 0.0) { // sc < 0 => the s=0 edge is visible
|
|
|
+ } else {
|
|
|
+ // get the closest points on the infinite lines
|
|
|
+ sN = b * e - c * d;
|
|
|
+ tN = a * e - b * d;
|
|
|
+ if (sN < 0.0) {
|
|
|
+ // sc < 0 => the s=0 edge is visible
|
|
|
sN = 0.0;
|
|
|
tN = e;
|
|
|
tD = c;
|
|
|
- } else if (sN > sD) { // sc > 1 => the s=1 edge is visible
|
|
|
+ } else if (sN > sD) {
|
|
|
+ // sc > 1 => the s=1 edge is visible
|
|
|
sN = sD;
|
|
|
tN = e + b;
|
|
|
tD = c;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (tN < 0.0) { // tc < 0 => the t=0 edge is visible
|
|
|
+ if (tN < 0.0) {
|
|
|
+ // tc < 0 => the t=0 edge is visible
|
|
|
tN = 0.0;
|
|
|
// recompute sc for this edge
|
|
|
if (-d < 0.0) {
|
|
|
sN = 0.0;
|
|
|
} else if (-d > a) {
|
|
|
sN = sD;
|
|
|
- }
|
|
|
- else {
|
|
|
+ } else {
|
|
|
sN = -d;
|
|
|
sD = a;
|
|
|
}
|
|
|
- } else if (tN > tD) { // tc > 1 => the t=1 edge is visible
|
|
|
+ } else if (tN > tD) {
|
|
|
+ // tc > 1 => the t=1 edge is visible
|
|
|
tN = tD;
|
|
|
// recompute sc for this edge
|
|
|
- if ((-d + b) < 0.0) {
|
|
|
+ if (-d + b < 0.0) {
|
|
|
sN = 0;
|
|
|
- } else if ((-d + b) > a) {
|
|
|
+ } else if (-d + b > a) {
|
|
|
sN = sD;
|
|
|
} else {
|
|
|
- sN = (-d + b);
|
|
|
+ sN = -d + b;
|
|
|
sD = a;
|
|
|
}
|
|
|
}
|
|
|
// finally do the division to get sc and tc
|
|
|
- sc = (Math.abs(sN) < Ray.smallnum ? 0.0 : sN / sD);
|
|
|
- tc = (Math.abs(tN) < Ray.smallnum ? 0.0 : tN / tD);
|
|
|
+ sc = Math.abs(sN) < Ray.smallnum ? 0.0 : sN / sD;
|
|
|
+ tc = Math.abs(tN) < Ray.smallnum ? 0.0 : tN / tD;
|
|
|
|
|
|
// get the difference of the two closest points
|
|
|
const qtc = TmpVectors.Vector3[4];
|
|
@@ -433,7 +431,7 @@ export class Ray {
|
|
|
const dP = TmpVectors.Vector3[6];
|
|
|
qsc.subtractToRef(qtc, dP); // = S1(sc) - S2(tc)
|
|
|
|
|
|
- var isIntersected = (tc > 0) && (tc <= this.length) && (dP.lengthSquared() < (threshold * threshold)); // return intersection result
|
|
|
+ var isIntersected = tc > 0 && tc <= this.length && dP.lengthSquared() < threshold * threshold; // return intersection result
|
|
|
|
|
|
if (isIntersected) {
|
|
|
return qsc.length();
|
|
@@ -484,16 +482,16 @@ export class 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
|
|
|
- */
|
|
|
+ * 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
|
|
|
+ */
|
|
|
public static CreateNewFromTo(origin: Vector3, end: Vector3, world: DeepImmutable<Matrix> = Matrix.IdentityReadOnly): Ray {
|
|
|
var direction = end.subtract(origin);
|
|
|
- var length = Math.sqrt((direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z));
|
|
|
+ var length = Math.sqrt(direction.x * direction.x + direction.y * direction.y + direction.z * direction.z);
|
|
|
direction.normalize();
|
|
|
|
|
|
return Ray.Transform(new Ray(origin, direction, length), world);
|
|
@@ -536,23 +534,23 @@ export class 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
|
|
|
- */
|
|
|
+ * 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
|
|
|
+ */
|
|
|
public unprojectRayToRef(sourceX: float, sourceY: float, viewportWidth: number, viewportHeight: number, world: DeepImmutable<Matrix>, view: DeepImmutable<Matrix>, projection: DeepImmutable<Matrix>): void {
|
|
|
var matrix = TmpVectors.Matrix[0];
|
|
|
world.multiplyToRef(view, matrix);
|
|
|
matrix.multiplyToRef(projection, matrix);
|
|
|
matrix.invert();
|
|
|
var nearScreenSource = TmpVectors.Vector3[0];
|
|
|
- nearScreenSource.x = sourceX / viewportWidth * 2 - 1;
|
|
|
- nearScreenSource.y = -(sourceY / viewportHeight * 2 - 1);
|
|
|
+ nearScreenSource.x = (sourceX / viewportWidth) * 2 - 1;
|
|
|
+ nearScreenSource.y = -((sourceY / viewportHeight) * 2 - 1);
|
|
|
nearScreenSource.z = -1.0;
|
|
|
var farScreenSource = TmpVectors.Vector3[1].copyFromFloats(nearScreenSource.x, nearScreenSource.y, 1.0);
|
|
|
const nearVec3 = TmpVectors.Vector3[2];
|
|
@@ -588,11 +586,10 @@ declare module "../scene" {
|
|
|
|
|
|
/** @hidden */
|
|
|
_internalMultiPick(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]>;
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-Scene.prototype.createPickingRay = function(x: number, y: number, world: Matrix, camera: Nullable<Camera>, cameraViewSpace = false): Ray {
|
|
|
+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);
|
|
@@ -600,7 +597,7 @@ Scene.prototype.createPickingRay = function(x: number, y: number, world: Matrix,
|
|
|
return result;
|
|
|
};
|
|
|
|
|
|
-Scene.prototype.createPickingRayToRef = function(x: number, y: number, world: Matrix, result: Ray, camera: Nullable<Camera>, cameraViewSpace = false): Scene {
|
|
|
+Scene.prototype.createPickingRayToRef = function (x: number, y: number, world: Matrix, result: Ray, camera: Nullable<Camera>, cameraViewSpace = false): Scene {
|
|
|
var engine = this.getEngine();
|
|
|
|
|
|
if (!camera) {
|
|
@@ -622,7 +619,7 @@ Scene.prototype.createPickingRayToRef = function(x: number, y: number, world: Ma
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
-Scene.prototype.createPickingRayInCameraSpace = function(x: number, y: number, camera?: Camera): Ray {
|
|
|
+Scene.prototype.createPickingRayInCameraSpace = function (x: number, y: number, camera?: Camera): Ray {
|
|
|
let result = Ray.Zero();
|
|
|
|
|
|
this.createPickingRayInCameraSpaceToRef(x, y, result, camera);
|
|
@@ -630,7 +627,7 @@ Scene.prototype.createPickingRayInCameraSpace = function(x: number, y: number, c
|
|
|
return result;
|
|
|
};
|
|
|
|
|
|
-Scene.prototype.createPickingRayInCameraSpaceToRef = function(x: number, y: number, result: Ray, camera?: Camera): Scene {
|
|
|
+Scene.prototype.createPickingRayInCameraSpaceToRef = function (x: number, y: number, result: Ray, camera?: Camera): Scene {
|
|
|
if (!PickingInfo) {
|
|
|
return this;
|
|
|
}
|
|
@@ -656,10 +653,7 @@ Scene.prototype.createPickingRayInCameraSpaceToRef = function(x: number, y: numb
|
|
|
return this;
|
|
|
};
|
|
|
|
|
|
-Scene.prototype._internalPick = function(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean,
|
|
|
- fastCheck?: boolean,
|
|
|
- onlyBoundingInfo?: boolean,
|
|
|
- trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo> {
|
|
|
+Scene.prototype._internalPick = function (rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean, onlyBoundingInfo?: boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo> {
|
|
|
if (!PickingInfo) {
|
|
|
return null;
|
|
|
}
|
|
@@ -699,9 +693,7 @@ Scene.prototype._internalPick = function(rayFunction: (world: Matrix) => Ray, pr
|
|
|
return pickingInfo || new PickingInfo();
|
|
|
};
|
|
|
|
|
|
-Scene.prototype._internalMultiPick = function(rayFunction: (world: Matrix) => Ray,
|
|
|
- predicate?: (mesh: AbstractMesh) => boolean,
|
|
|
- trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {
|
|
|
+Scene.prototype._internalMultiPick = function (rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {
|
|
|
if (!PickingInfo) {
|
|
|
return null;
|
|
|
}
|
|
@@ -732,100 +724,122 @@ Scene.prototype._internalMultiPick = function(rayFunction: (world: Matrix) => Ra
|
|
|
return pickingInfos;
|
|
|
};
|
|
|
|
|
|
-Scene.prototype.pickWithBoundingInfo = function(x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean,
|
|
|
- fastCheck?: boolean, camera?: Nullable<Camera>): Nullable<PickingInfo> {
|
|
|
+Scene.prototype.pickWithBoundingInfo = 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();
|
|
|
- }
|
|
|
+ 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, true);
|
|
|
+ this.createPickingRayToRef(x, y, world, this._tempPickingRay, camera || null);
|
|
|
+ return this._tempPickingRay;
|
|
|
+ },
|
|
|
+ predicate,
|
|
|
+ fastCheck,
|
|
|
+ true
|
|
|
+ );
|
|
|
if (result) {
|
|
|
result.ray = this.createPickingRay(x, y, Matrix.Identity(), camera || null);
|
|
|
}
|
|
|
return result;
|
|
|
};
|
|
|
|
|
|
-Scene.prototype.pick = function(x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean,
|
|
|
- fastCheck?: boolean, camera?: Nullable<Camera>,
|
|
|
- trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo> {
|
|
|
+Scene.prototype.pick = function (x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean, camera?: Nullable<Camera>, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo> {
|
|
|
if (!PickingInfo) {
|
|
|
return null;
|
|
|
}
|
|
|
- var result = this._internalPick((world) => {
|
|
|
- if (!this._tempPickingRay) {
|
|
|
- this._tempPickingRay = Ray.Zero();
|
|
|
- }
|
|
|
+ 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, false, trianglePredicate);
|
|
|
+ this.createPickingRayToRef(x, y, world, this._tempPickingRay, camera || null);
|
|
|
+ return this._tempPickingRay;
|
|
|
+ },
|
|
|
+ predicate,
|
|
|
+ fastCheck,
|
|
|
+ false,
|
|
|
+ trianglePredicate
|
|
|
+ );
|
|
|
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, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo> {
|
|
|
- var result = this._internalPick((world) => {
|
|
|
- if (!this._pickWithRayInverseMatrix) {
|
|
|
- this._pickWithRayInverseMatrix = Matrix.Identity();
|
|
|
- }
|
|
|
- world.invertToRef(this._pickWithRayInverseMatrix);
|
|
|
+Scene.prototype.pickWithRay = function (ray: Ray, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean, trianglePredicate?: TrianglePickingPredicate): 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();
|
|
|
- }
|
|
|
+ if (!this._cachedRayForTransform) {
|
|
|
+ this._cachedRayForTransform = Ray.Zero();
|
|
|
+ }
|
|
|
|
|
|
- Ray.TransformToRef(ray, this._pickWithRayInverseMatrix, this._cachedRayForTransform);
|
|
|
- return this._cachedRayForTransform;
|
|
|
- }, predicate, fastCheck, false, trianglePredicate);
|
|
|
+ Ray.TransformToRef(ray, this._pickWithRayInverseMatrix, this._cachedRayForTransform);
|
|
|
+ return this._cachedRayForTransform;
|
|
|
+ },
|
|
|
+ predicate,
|
|
|
+ fastCheck,
|
|
|
+ false,
|
|
|
+ trianglePredicate
|
|
|
+ );
|
|
|
if (result) {
|
|
|
result.ray = ray;
|
|
|
}
|
|
|
return result;
|
|
|
};
|
|
|
|
|
|
-Scene.prototype.multiPick = function(x: number, y: number,
|
|
|
- predicate?: (mesh: AbstractMesh) => boolean, camera?: Camera, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {
|
|
|
+Scene.prototype.multiPick = function (x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean, camera?: Camera, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {
|
|
|
return this._internalMultiPick((world) => this.createPickingRay(x, y, world, camera || null), predicate, trianglePredicate);
|
|
|
};
|
|
|
|
|
|
-Scene.prototype.multiPickWithRay = function(ray: Ray,
|
|
|
- predicate: (mesh: AbstractMesh) => boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {
|
|
|
- return this._internalMultiPick((world) => {
|
|
|
- if (!this._pickWithRayInverseMatrix) {
|
|
|
- this._pickWithRayInverseMatrix = Matrix.Identity();
|
|
|
- }
|
|
|
- world.invertToRef(this._pickWithRayInverseMatrix);
|
|
|
+Scene.prototype.multiPickWithRay = function (ray: Ray, predicate: (mesh: AbstractMesh) => boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]> {
|
|
|
+ return this._internalMultiPick(
|
|
|
+ (world) => {
|
|
|
+ if (!this._pickWithRayInverseMatrix) {
|
|
|
+ this._pickWithRayInverseMatrix = Matrix.Identity();
|
|
|
+ }
|
|
|
+ world.invertToRef(this._pickWithRayInverseMatrix);
|
|
|
|
|
|
- if (!this._cachedRayForTransform) {
|
|
|
- this._cachedRayForTransform = Ray.Zero();
|
|
|
- }
|
|
|
+ if (!this._cachedRayForTransform) {
|
|
|
+ this._cachedRayForTransform = Ray.Zero();
|
|
|
+ }
|
|
|
+
|
|
|
+ Ray.TransformToRef(ray, this._pickWithRayInverseMatrix, this._cachedRayForTransform);
|
|
|
+ return this._cachedRayForTransform;
|
|
|
+ },
|
|
|
+ predicate,
|
|
|
+ trianglePredicate
|
|
|
+ );
|
|
|
+};
|
|
|
|
|
|
- Ray.TransformToRef(ray, this._pickWithRayInverseMatrix, this._cachedRayForTransform);
|
|
|
- return this._cachedRayForTransform;
|
|
|
- }, predicate, trianglePredicate);
|
|
|
+Camera.prototype.getForwardRay = function (length = 100, transform?: Matrix, origin?: Vector3): Ray {
|
|
|
+ return this.getForwardRayToRef(new Ray(Vector3.Zero(), Vector3.Zero(), length), length, transform, origin);
|
|
|
};
|
|
|
|
|
|
-Camera.prototype.getForwardRay = function(length = 100, transform?: Matrix, origin?: Vector3): Ray {
|
|
|
+Camera.prototype.getForwardRayToRef = function (refRay: Ray, length = 100, transform?: Matrix, origin?: Vector3): Ray {
|
|
|
if (!transform) {
|
|
|
transform = this.getWorldMatrix();
|
|
|
}
|
|
|
+ refRay.length = length;
|
|
|
|
|
|
if (!origin) {
|
|
|
- origin = this.position;
|
|
|
+ refRay.origin.copyFrom(this.position);
|
|
|
+ } else {
|
|
|
+ refRay.origin.copyFrom(origin);
|
|
|
}
|
|
|
- var forward = this._scene.useRightHandedSystem ? new Vector3(0, 0, -1) : new Vector3(0, 0, 1);
|
|
|
- var forwardWorld = Vector3.TransformNormal(forward, transform);
|
|
|
+ TmpVectors.Vector3[2].set(0, 0, this._scene.useRightHandedSystem ? -1 : 1);
|
|
|
+ Vector3.TransformNormalToRef(TmpVectors.Vector3[2], transform, TmpVectors.Vector3[3]);
|
|
|
|
|
|
- var direction = Vector3.Normalize(forwardWorld);
|
|
|
+ Vector3.NormalizeToRef(TmpVectors.Vector3[3], refRay.direction);
|
|
|
|
|
|
- return new Ray(origin, direction, length);
|
|
|
+ return refRay;
|
|
|
};
|