Skip to content
Permalink
b948e75f0a
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
5604 lines (5034 sloc) 210 KB
import { Scalar } from "./math.scalar";
import { Epsilon } from './math.constants';
import { Viewport } from './math.viewport';
import { DeepImmutable, Nullable, FloatArray, float } from "../types";
import { ArrayTools } from '../Misc/arrayTools';
import { IPlaneLike } from './math.like';
import { _TypeStore } from '../Misc/typeStore';
import { Plane } from './math.plane';
import { PerformanceConfigurator } from '../Engines/performanceConfigurator';
/**
* Class representing a vector containing 2 coordinates
*/
export class Vector2 {
/**
* Creates a new Vector2 from the given x and y coordinates
* @param x defines the first coordinate
* @param y defines the second coordinate
*/
constructor(
/** defines the first coordinate */
public x: number = 0,
/** defines the second coordinate */
public y: number = 0) {
}
/**
* Gets a string with the Vector2 coordinates
* @returns a string with the Vector2 coordinates
*/
public toString(): string {
return "{X: " + this.x + " Y:" + this.y + "}";
}
/**
* Gets class name
* @returns the string "Vector2"
*/
public getClassName(): string {
return "Vector2";
}
/**
* Gets current vector hash code
* @returns the Vector2 hash code as a number
*/
public getHashCode(): number {
let hash = this.x | 0;
hash = (hash * 397) ^ (this.y | 0);
return hash;
}
// Operators
/**
* Sets the Vector2 coordinates in the given array or Float32Array from the given index.
* @param array defines the source array
* @param index defines the offset in source array
* @returns the current Vector2
*/
public toArray(array: FloatArray, index: number = 0): Vector2 {
array[index] = this.x;
array[index + 1] = this.y;
return this;
}
/**
* Update the current vector from an array
* @param array defines the destination array
* @param index defines the offset in the destination array
* @returns the current Vector3
*/
public fromArray(array: FloatArray, index: number = 0): Vector2 {
Vector2.FromArrayToRef(array, index, this);
return this;
}
/**
* Copy the current vector to an array
* @returns a new array with 2 elements: the Vector2 coordinates.
*/
public asArray(): number[] {
var result = new Array<number>();
this.toArray(result, 0);
return result;
}
/**
* Sets the Vector2 coordinates with the given Vector2 coordinates
* @param source defines the source Vector2
* @returns the current updated Vector2
*/
public copyFrom(source: DeepImmutable<Vector2>): Vector2 {
this.x = source.x;
this.y = source.y;
return this;
}
/**
* Sets the Vector2 coordinates with the given floats
* @param x defines the first coordinate
* @param y defines the second coordinate
* @returns the current updated Vector2
*/
public copyFromFloats(x: number, y: number): Vector2 {
this.x = x;
this.y = y;
return this;
}
/**
* Sets the Vector2 coordinates with the given floats
* @param x defines the first coordinate
* @param y defines the second coordinate
* @returns the current updated Vector2
*/
public set(x: number, y: number): Vector2 {
return this.copyFromFloats(x, y);
}
/**
* Add another vector with the current one
* @param otherVector defines the other vector
* @returns a new Vector2 set with the addition of the current Vector2 and the given one coordinates
*/
public add(otherVector: DeepImmutable<Vector2>): Vector2 {
return new Vector2(this.x + otherVector.x, this.y + otherVector.y);
}
/**
* Sets the "result" coordinates with the addition of the current Vector2 and the given one coordinates
* @param otherVector defines the other vector
* @param result defines the target vector
* @returns the unmodified current Vector2
*/
public addToRef(otherVector: DeepImmutable<Vector2>, result: Vector2): Vector2 {
result.x = this.x + otherVector.x;
result.y = this.y + otherVector.y;
return this;
}
/**
* Set the Vector2 coordinates by adding the given Vector2 coordinates
* @param otherVector defines the other vector
* @returns the current updated Vector2
*/
public addInPlace(otherVector: DeepImmutable<Vector2>): Vector2 {
this.x += otherVector.x;
this.y += otherVector.y;
return this;
}
/**
* Gets a new Vector2 by adding the current Vector2 coordinates to the given Vector3 x, y coordinates
* @param otherVector defines the other vector
* @returns a new Vector2
*/
public addVector3(otherVector: Vector3): Vector2 {
return new Vector2(this.x + otherVector.x, this.y + otherVector.y);
}
/**
* Gets a new Vector2 set with the subtracted coordinates of the given one from the current Vector2
* @param otherVector defines the other vector
* @returns a new Vector2
*/
public subtract(otherVector: Vector2): Vector2 {
return new Vector2(this.x - otherVector.x, this.y - otherVector.y);
}
/**
* Sets the "result" coordinates with the subtraction of the given one from the current Vector2 coordinates.
* @param otherVector defines the other vector
* @param result defines the target vector
* @returns the unmodified current Vector2
*/
public subtractToRef(otherVector: DeepImmutable<Vector2>, result: Vector2): Vector2 {
result.x = this.x - otherVector.x;
result.y = this.y - otherVector.y;
return this;
}
/**
* Sets the current Vector2 coordinates by subtracting from it the given one coordinates
* @param otherVector defines the other vector
* @returns the current updated Vector2
*/
public subtractInPlace(otherVector: DeepImmutable<Vector2>): Vector2 {
this.x -= otherVector.x;
this.y -= otherVector.y;
return this;
}
/**
* Multiplies in place the current Vector2 coordinates by the given ones
* @param otherVector defines the other vector
* @returns the current updated Vector2
*/
public multiplyInPlace(otherVector: DeepImmutable<Vector2>): Vector2 {
this.x *= otherVector.x;
this.y *= otherVector.y;
return this;
}
/**
* Returns a new Vector2 set with the multiplication of the current Vector2 and the given one coordinates
* @param otherVector defines the other vector
* @returns a new Vector2
*/
public multiply(otherVector: DeepImmutable<Vector2>): Vector2 {
return new Vector2(this.x * otherVector.x, this.y * otherVector.y);
}
/**
* Sets "result" coordinates with the multiplication of the current Vector2 and the given one coordinates
* @param otherVector defines the other vector
* @param result defines the target vector
* @returns the unmodified current Vector2
*/
public multiplyToRef(otherVector: DeepImmutable<Vector2>, result: Vector2): Vector2 {
result.x = this.x * otherVector.x;
result.y = this.y * otherVector.y;
return this;
}
/**
* Gets a new Vector2 set with the Vector2 coordinates multiplied by the given floats
* @param x defines the first coordinate
* @param y defines the second coordinate
* @returns a new Vector2
*/
public multiplyByFloats(x: number, y: number): Vector2 {
return new Vector2(this.x * x, this.y * y);
}
/**
* Returns a new Vector2 set with the Vector2 coordinates divided by the given one coordinates
* @param otherVector defines the other vector
* @returns a new Vector2
*/
public divide(otherVector: Vector2): Vector2 {
return new Vector2(this.x / otherVector.x, this.y / otherVector.y);
}
/**
* Sets the "result" coordinates with the Vector2 divided by the given one coordinates
* @param otherVector defines the other vector
* @param result defines the target vector
* @returns the unmodified current Vector2
*/
public divideToRef(otherVector: DeepImmutable<Vector2>, result: Vector2): Vector2 {
result.x = this.x / otherVector.x;
result.y = this.y / otherVector.y;
return this;
}
/**
* Divides the current Vector2 coordinates by the given ones
* @param otherVector defines the other vector
* @returns the current updated Vector2
*/
public divideInPlace(otherVector: DeepImmutable<Vector2>): Vector2 {
return this.divideToRef(otherVector, this);
}
/**
* Gets a new Vector2 with current Vector2 negated coordinates
* @returns a new Vector2
*/
public negate(): Vector2 {
return new Vector2(-this.x, -this.y);
}
/**
* Negate this vector in place
* @returns this
*/
public negateInPlace(): Vector2 {
this.x *= -1;
this.y *= -1;
return this;
}
/**
* Negate the current Vector2 and stores the result in the given vector "result" coordinates
* @param result defines the Vector3 object where to store the result
* @returns the current Vector2
*/
public negateToRef(result: Vector2): Vector2 {
return result.copyFromFloats(this.x * -1, this.y * -1);
}
/**
* Multiply the Vector2 coordinates by scale
* @param scale defines the scaling factor
* @returns the current updated Vector2
*/
public scaleInPlace(scale: number): Vector2 {
this.x *= scale;
this.y *= scale;
return this;
}
/**
* Returns a new Vector2 scaled by "scale" from the current Vector2
* @param scale defines the scaling factor
* @returns a new Vector2
*/
public scale(scale: number): Vector2 {
let result = new Vector2(0, 0);
this.scaleToRef(scale, result);
return result;
}
/**
* Scale the current Vector2 values by a factor to a given Vector2
* @param scale defines the scale factor
* @param result defines the Vector2 object where to store the result
* @returns the unmodified current Vector2
*/
public scaleToRef(scale: number, result: Vector2): Vector2 {
result.x = this.x * scale;
result.y = this.y * scale;
return this;
}
/**
* Scale the current Vector2 values by a factor and add the result to a given Vector2
* @param scale defines the scale factor
* @param result defines the Vector2 object where to store the result
* @returns the unmodified current Vector2
*/
public scaleAndAddToRef(scale: number, result: Vector2): Vector2 {
result.x += this.x * scale;
result.y += this.y * scale;
return this;
}
/**
* Gets a boolean if two vectors are equals
* @param otherVector defines the other vector
* @returns true if the given vector coordinates strictly equal the current Vector2 ones
*/
public equals(otherVector: DeepImmutable<Vector2>): boolean {
return otherVector && this.x === otherVector.x && this.y === otherVector.y;
}
/**
* Gets a boolean if two vectors are equals (using an epsilon value)
* @param otherVector defines the other vector
* @param epsilon defines the minimal distance to consider equality
* @returns true if the given vector coordinates are close to the current ones by a distance of epsilon.
*/
public equalsWithEpsilon(otherVector: DeepImmutable<Vector2>, epsilon: number = Epsilon): boolean {
return otherVector && Scalar.WithinEpsilon(this.x, otherVector.x, epsilon) && Scalar.WithinEpsilon(this.y, otherVector.y, epsilon);
}
/**
* Gets a new Vector2 from current Vector2 floored values
* @returns a new Vector2
*/
public floor(): Vector2 {
return new Vector2(Math.floor(this.x), Math.floor(this.y));
}
/**
* Gets a new Vector2 from current Vector2 floored values
* @returns a new Vector2
*/
public fract(): Vector2 {
return new Vector2(this.x - Math.floor(this.x), this.y - Math.floor(this.y));
}
// Properties
/**
* Gets the length of the vector
* @returns the vector length (float)
*/
public length(): number {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
/**
* Gets the vector squared length
* @returns the vector squared length (float)
*/
public lengthSquared(): number {
return (this.x * this.x + this.y * this.y);
}
// Methods
/**
* Normalize the vector
* @returns the current updated Vector2
*/
public normalize(): Vector2 {
var len = this.length();
if (len === 0) {
return this;
}
this.x /= len;
this.y /= len;
return this;
}
/**
* Gets a new Vector2 copied from the Vector2
* @returns a new Vector2
*/
public clone(): Vector2 {
return new Vector2(this.x, this.y);
}
// Statics
/**
* Gets a new Vector2(0, 0)
* @returns a new Vector2
*/
public static Zero(): Vector2 {
return new Vector2(0, 0);
}
/**
* Gets a new Vector2(1, 1)
* @returns a new Vector2
*/
public static One(): Vector2 {
return new Vector2(1, 1);
}
/**
* Gets a new Vector2 set from the given index element of the given array
* @param array defines the data source
* @param offset defines the offset in the data source
* @returns a new Vector2
*/
public static FromArray(array: DeepImmutable<ArrayLike<number>>, offset: number = 0): Vector2 {
return new Vector2(array[offset], array[offset + 1]);
}
/**
* Sets "result" from the given index element of the given array
* @param array defines the data source
* @param offset defines the offset in the data source
* @param result defines the target vector
*/
public static FromArrayToRef(array: DeepImmutable<ArrayLike<number>>, offset: number, result: Vector2): void {
result.x = array[offset];
result.y = array[offset + 1];
}
/**
* Gets a new Vector2 located for "amount" (float) on the CatmullRom spline defined by the given four Vector2
* @param value1 defines 1st point of control
* @param value2 defines 2nd point of control
* @param value3 defines 3rd point of control
* @param value4 defines 4th point of control
* @param amount defines the interpolation factor
* @returns a new Vector2
*/
public static CatmullRom(value1: DeepImmutable<Vector2>, value2: DeepImmutable<Vector2>, value3: DeepImmutable<Vector2>, value4: DeepImmutable<Vector2>, amount: number): Vector2 {
var squared = amount * amount;
var cubed = amount * squared;
var x = 0.5 * ((((2.0 * value2.x) + ((-value1.x + value3.x) * amount)) +
(((((2.0 * value1.x) - (5.0 * value2.x)) + (4.0 * value3.x)) - value4.x) * squared)) +
((((-value1.x + (3.0 * value2.x)) - (3.0 * value3.x)) + value4.x) * cubed));
var y = 0.5 * ((((2.0 * value2.y) + ((-value1.y + value3.y) * amount)) +
(((((2.0 * value1.y) - (5.0 * value2.y)) + (4.0 * value3.y)) - value4.y) * squared)) +
((((-value1.y + (3.0 * value2.y)) - (3.0 * value3.y)) + value4.y) * cubed));
return new Vector2(x, y);
}
/**
* Returns a new Vector2 set with same the coordinates than "value" ones if the vector "value" is in the square defined by "min" and "max".
* If a coordinate of "value" is lower than "min" coordinates, the returned Vector2 is given this "min" coordinate.
* If a coordinate of "value" is greater than "max" coordinates, the returned Vector2 is given this "max" coordinate
* @param value defines the value to clamp
* @param min defines the lower limit
* @param max defines the upper limit
* @returns a new Vector2
*/
public static Clamp(value: DeepImmutable<Vector2>, min: DeepImmutable<Vector2>, max: DeepImmutable<Vector2>): Vector2 {
var x = value.x;
x = (x > max.x) ? max.x : x;
x = (x < min.x) ? min.x : x;
var y = value.y;
y = (y > max.y) ? max.y : y;
y = (y < min.y) ? min.y : y;
return new Vector2(x, y);
}
/**
* Returns a new Vector2 located for "amount" (float) on the Hermite spline defined by the vectors "value1", "value3", "tangent1", "tangent2"
* @param value1 defines the 1st control point
* @param tangent1 defines the outgoing tangent
* @param value2 defines the 2nd control point
* @param tangent2 defines the incoming tangent
* @param amount defines the interpolation factor
* @returns a new Vector2
*/
public static Hermite(value1: DeepImmutable<Vector2>, tangent1: DeepImmutable<Vector2>, value2: DeepImmutable<Vector2>, tangent2: DeepImmutable<Vector2>, amount: number): Vector2 {
var squared = amount * amount;
var cubed = amount * squared;
var part1 = ((2.0 * cubed) - (3.0 * squared)) + 1.0;
var part2 = (-2.0 * cubed) + (3.0 * squared);
var part3 = (cubed - (2.0 * squared)) + amount;
var part4 = cubed - squared;
var x = (((value1.x * part1) + (value2.x * part2)) + (tangent1.x * part3)) + (tangent2.x * part4);
var y = (((value1.y * part1) + (value2.y * part2)) + (tangent1.y * part3)) + (tangent2.y * part4);
return new Vector2(x, y);
}
/**
* Returns a new Vector2 located for "amount" (float) on the linear interpolation between the vector "start" adn the vector "end".
* @param start defines the start vector
* @param end defines the end vector
* @param amount defines the interpolation factor
* @returns a new Vector2
*/
public static Lerp(start: DeepImmutable<Vector2>, end: DeepImmutable<Vector2>, amount: number): Vector2 {
var x = start.x + ((end.x - start.x) * amount);
var y = start.y + ((end.y - start.y) * amount);
return new Vector2(x, y);
}
/**
* Gets the dot product of the vector "left" and the vector "right"
* @param left defines first vector
* @param right defines second vector
* @returns the dot product (float)
*/
public static Dot(left: DeepImmutable<Vector2>, right: DeepImmutable<Vector2>): number {
return left.x * right.x + left.y * right.y;
}
/**
* Returns a new Vector2 equal to the normalized given vector
* @param vector defines the vector to normalize
* @returns a new Vector2
*/
public static Normalize(vector: DeepImmutable<Vector2>): Vector2 {
var newVector = vector.clone();
newVector.normalize();
return newVector;
}
/**
* Gets a new Vector2 set with the minimal coordinate values from the "left" and "right" vectors
* @param left defines 1st vector
* @param right defines 2nd vector
* @returns a new Vector2
*/
public static Minimize(left: DeepImmutable<Vector2>, right: DeepImmutable<Vector2>): Vector2 {
var x = (left.x < right.x) ? left.x : right.x;
var y = (left.y < right.y) ? left.y : right.y;
return new Vector2(x, y);
}
/**
* Gets a new Vecto2 set with the maximal coordinate values from the "left" and "right" vectors
* @param left defines 1st vector
* @param right defines 2nd vector
* @returns a new Vector2
*/
public static Maximize(left: DeepImmutable<Vector2>, right: DeepImmutable<Vector2>): Vector2 {
var x = (left.x > right.x) ? left.x : right.x;
var y = (left.y > right.y) ? left.y : right.y;
return new Vector2(x, y);
}
/**
* Gets a new Vector2 set with the transformed coordinates of the given vector by the given transformation matrix
* @param vector defines the vector to transform
* @param transformation defines the matrix to apply
* @returns a new Vector2
*/
public static Transform(vector: DeepImmutable<Vector2>, transformation: DeepImmutable<Matrix>): Vector2 {
let r = Vector2.Zero();
Vector2.TransformToRef(vector, transformation, r);
return r;
}
/**
* Transforms the given vector coordinates by the given transformation matrix and stores the result in the vector "result" coordinates
* @param vector defines the vector to transform
* @param transformation defines the matrix to apply
* @param result defines the target vector
*/
public static TransformToRef(vector: DeepImmutable<Vector2>, transformation: DeepImmutable<Matrix>, result: Vector2) {
const m = transformation.m;
var x = (vector.x * m[0]) + (vector.y * m[4]) + m[12];
var y = (vector.x * m[1]) + (vector.y * m[5]) + m[13];
result.x = x;
result.y = y;
}
/**
* Determines if a given vector is included in a triangle
* @param p defines the vector to test
* @param p0 defines 1st triangle point
* @param p1 defines 2nd triangle point
* @param p2 defines 3rd triangle point
* @returns true if the point "p" is in the triangle defined by the vertors "p0", "p1", "p2"
*/
public static PointInTriangle(p: DeepImmutable<Vector2>, p0: DeepImmutable<Vector2>, p1: DeepImmutable<Vector2>, p2: DeepImmutable<Vector2>) {
let a = 1 / 2 * (-p1.y * p2.x + p0.y * (-p1.x + p2.x) + p0.x * (p1.y - p2.y) + p1.x * p2.y);
let sign = a < 0 ? -1 : 1;
let s = (p0.y * p2.x - p0.x * p2.y + (p2.y - p0.y) * p.x + (p0.x - p2.x) * p.y) * sign;
let t = (p0.x * p1.y - p0.y * p1.x + (p0.y - p1.y) * p.x + (p1.x - p0.x) * p.y) * sign;
return s > 0 && t > 0 && (s + t) < 2 * a * sign;
}
/**
* Gets the distance between the vectors "value1" and "value2"
* @param value1 defines first vector
* @param value2 defines second vector
* @returns the distance between vectors
*/
public static Distance(value1: DeepImmutable<Vector2>, value2: DeepImmutable<Vector2>): number {
return Math.sqrt(Vector2.DistanceSquared(value1, value2));
}
/**
* Returns the squared distance between the vectors "value1" and "value2"
* @param value1 defines first vector
* @param value2 defines second vector
* @returns the squared distance between vectors
*/
public static DistanceSquared(value1: DeepImmutable<Vector2>, value2: DeepImmutable<Vector2>): number {
var x = value1.x - value2.x;
var y = value1.y - value2.y;
return (x * x) + (y * y);
}
/**
* Gets a new Vector2 located at the center of the vectors "value1" and "value2"
* @param value1 defines first vector
* @param value2 defines second vector
* @returns a new Vector2
*/
public static Center(value1: DeepImmutable<Vector2>, value2: DeepImmutable<Vector2>): Vector2 {
var center = value1.add(value2);
center.scaleInPlace(0.5);
return center;
}
/**
* Gets the shortest distance (float) between the point "p" and the segment defined by the two points "segA" and "segB".
* @param p defines the middle point
* @param segA defines one point of the segment
* @param segB defines the other point of the segment
* @returns the shortest distance
*/
public static DistanceOfPointFromSegment(p: DeepImmutable<Vector2>, segA: DeepImmutable<Vector2>, segB: DeepImmutable<Vector2>): number {
let l2 = Vector2.DistanceSquared(segA, segB);
if (l2 === 0.0) {
return Vector2.Distance(p, segA);
}
let v = segB.subtract(segA);
let t = Math.max(0, Math.min(1, Vector2.Dot(p.subtract(segA), v) / l2));
let proj = segA.add(v.multiplyByFloats(t, t));
return Vector2.Distance(p, proj);
}
}
/**
* Class used to store (x,y,z) vector representation
* A Vector3 is the main object used in 3D geometry
* It can represent etiher the coordinates of a point the space, either a direction
* Reminder: js uses a left handed forward facing system
*/
export class Vector3 {
private static _UpReadOnly = Vector3.Up() as DeepImmutable<Vector3>;
private static _ZeroReadOnly = Vector3.Zero() as DeepImmutable<Vector3>;
/** @hidden */
public _x: number;
/** @hidden */
public _y: number;
/** @hidden */
public _z: number;
/** @hidden */
public _isDirty = true;
/** Gets or sets the x coordinate */
public get x() {
return this._x;
}
public set x(value: number) {
this._x = value;
this._isDirty = true;
}
/** Gets or sets the y coordinate */
public get y() {
return this._y;
}
public set y(value: number) {
this._y = value;
this._isDirty = true;
}
/** Gets or sets the z coordinate */
public get z() {
return this._z;
}
public set z(value: number) {
this._z = value;
this._isDirty = true;
}
/**
* Creates a new Vector3 object from the given x, y, z (floats) coordinates.
* @param x defines the first coordinates (on X axis)
* @param y defines the second coordinates (on Y axis)
* @param z defines the third coordinates (on Z axis)
*/
constructor(
x: number = 0,
y: number = 0,
z: number = 0
) {
this._x = x;
this._y = y;
this._z = z;
}
/**
* Creates a string representation of the Vector3
* @returns a string with the Vector3 coordinates.
*/
public toString(): string {
return "{X: " + this._x + " Y:" + this._y + " Z:" + this._z + "}";
}
/**
* Gets the class name
* @returns the string "Vector3"
*/
public getClassName(): string {
return "Vector3";
}
/**
* Creates the Vector3 hash code
* @returns a number which tends to be unique between Vector3 instances
*/
public getHashCode(): number {
let hash = this._x | 0;
hash = (hash * 397) ^ (this._y | 0);
hash = (hash * 397) ^ (this._z | 0);
return hash;
}
// Operators
/**
* Creates an array containing three elements : the coordinates of the Vector3
* @returns a new array of numbers
*/
public asArray(): number[] {
var result: number[] = [];
this.toArray(result, 0);
return result;
}
/**
* Populates the given array or Float32Array from the given index with the successive coordinates of the Vector3
* @param array defines the destination array
* @param index defines the offset in the destination array
* @returns the current Vector3
*/
public toArray(array: FloatArray, index: number = 0): Vector3 {
array[index] = this._x;
array[index + 1] = this._y;
array[index + 2] = this._z;
return this;
}
/**
* Update the current vector from an array
* @param array defines the destination array
* @param index defines the offset in the destination array
* @returns the current Vector3
*/
public fromArray(array: FloatArray, index: number = 0): Vector3 {
Vector3.FromArrayToRef(array, index, this);
return this;
}
/**
* Converts the current Vector3 into a quaternion (considering that the Vector3 contains Euler angles representation of a rotation)
* @returns a new Quaternion object, computed from the Vector3 coordinates
*/
public toQuaternion(): Quaternion {
return Quaternion.RotationYawPitchRoll(this._y, this._x, this._z);
}
/**
* Adds the given vector to the current Vector3
* @param otherVector defines the second operand
* @returns the current updated Vector3
*/
public addInPlace(otherVector: DeepImmutable<Vector3>): Vector3 {
return this.addInPlaceFromFloats(otherVector._x, otherVector._y, otherVector._z);
}
/**
* Adds the given coordinates to the current Vector3
* @param x defines the x coordinate of the operand
* @param y defines the y coordinate of the operand
* @param z defines the z coordinate of the operand
* @returns the current updated Vector3
*/
public addInPlaceFromFloats(x: number, y: number, z: number): Vector3 {
this.x += x;
this.y += y;
this.z += z;
return this;
}
/**
* Gets a new Vector3, result of the addition the current Vector3 and the given vector
* @param otherVector defines the second operand
* @returns the resulting Vector3
*/
public add(otherVector: DeepImmutable<Vector3>): Vector3 {
return new Vector3(this._x + otherVector._x, this._y + otherVector._y, this._z + otherVector._z);
}
/**
* Adds the current Vector3 to the given one and stores the result in the vector "result"
* @param otherVector defines the second operand
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
*/
public addToRef(otherVector: DeepImmutable<Vector3>, result: Vector3): Vector3 {
return result.copyFromFloats(this._x + otherVector._x, this._y + otherVector._y, this._z + otherVector._z);
}
/**
* Subtract the given vector from the current Vector3
* @param otherVector defines the second operand
* @returns the current updated Vector3
*/
public subtractInPlace(otherVector: DeepImmutable<Vector3>): Vector3 {
this.x -= otherVector._x;
this.y -= otherVector._y;
this.z -= otherVector._z;
return this;
}
/**
* Returns a new Vector3, result of the subtraction of the given vector from the current Vector3
* @param otherVector defines the second operand
* @returns the resulting Vector3
*/
public subtract(otherVector: DeepImmutable<Vector3>): Vector3 {
return new Vector3(this._x - otherVector._x, this._y - otherVector._y, this._z - otherVector._z);
}
/**
* Subtracts the given vector from the current Vector3 and stores the result in the vector "result".
* @param otherVector defines the second operand
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
*/
public subtractToRef(otherVector: DeepImmutable<Vector3>, result: Vector3): Vector3 {
return this.subtractFromFloatsToRef(otherVector._x, otherVector._y, otherVector._z, result);
}
/**
* Returns a new Vector3 set with the subtraction of the given floats from the current Vector3 coordinates
* @param x defines the x coordinate of the operand
* @param y defines the y coordinate of the operand
* @param z defines the z coordinate of the operand
* @returns the resulting Vector3
*/
public subtractFromFloats(x: number, y: number, z: number): Vector3 {
return new Vector3(this._x - x, this._y - y, this._z - z);
}
/**
* Subtracts the given floats from the current Vector3 coordinates and set the given vector "result" with this result
* @param x defines the x coordinate of the operand
* @param y defines the y coordinate of the operand
* @param z defines the z coordinate of the operand
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
*/
public subtractFromFloatsToRef(x: number, y: number, z: number, result: Vector3): Vector3 {
return result.copyFromFloats(this._x - x, this._y - y, this._z - z);
}
/**
* Gets a new Vector3 set with the current Vector3 negated coordinates
* @returns a new Vector3
*/
public negate(): Vector3 {
return new Vector3(-this._x, -this._y, -this._z);
}
/**
* Negate this vector in place
* @returns this
*/
public negateInPlace(): Vector3 {
this.x *= -1;
this.y *= -1;
this.z *= -1;
return this;
}
/**
* Negate the current Vector3 and stores the result in the given vector "result" coordinates
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
*/
public negateToRef(result: Vector3): Vector3 {
return result.copyFromFloats(this._x * -1, this._y * -1, this._z * -1);
}
/**
* Multiplies the Vector3 coordinates by the float "scale"
* @param scale defines the multiplier factor
* @returns the current updated Vector3
*/
public scaleInPlace(scale: number): Vector3 {
this.x *= scale;
this.y *= scale;
this.z *= scale;
return this;
}
/**
* Returns a new Vector3 set with the current Vector3 coordinates multiplied by the float "scale"
* @param scale defines the multiplier factor
* @returns a new Vector3
*/
public scale(scale: number): Vector3 {
return new Vector3(this._x * scale, this._y * scale, this._z * scale);
}
/**
* Multiplies the current Vector3 coordinates by the float "scale" and stores the result in the given vector "result" coordinates
* @param scale defines the multiplier factor
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
*/
public scaleToRef(scale: number, result: Vector3): Vector3 {
return result.copyFromFloats(this._x * scale, this._y * scale, this._z * scale);
}
/**
* Scale the current Vector3 values by a factor and add the result to a given Vector3
* @param scale defines the scale factor
* @param result defines the Vector3 object where to store the result
* @returns the unmodified current Vector3
*/
public scaleAndAddToRef(scale: number, result: Vector3): Vector3 {
return result.addInPlaceFromFloats(this._x * scale, this._y * scale, this._z * scale);
}
/**
* Projects the current vector3 to a plane along a ray starting from a specified origin and directed towards the point.
* @param origin defines the origin of the projection ray
* @param plane defines the plane to project to
* @returns the projected vector3
*/
public projectOnPlane(plane: Plane, origin: Vector3): Vector3 {
let result = Vector3.Zero();
this.projectOnPlaneToRef(plane, origin, result);
return result;
}
/**
* Projects the current vector3 to a plane along a ray starting from a specified origin and directed towards the point.
* @param origin defines the origin of the projection ray
* @param plane defines the plane to project to
* @param result defines the Vector3 where to store the result
*/
public projectOnPlaneToRef(plane: Plane, origin: Vector3, result: Vector3): void {
let n = plane.normal;
let d = plane.d;
let V = MathTmp.Vector3[0];
// ray direction
this.subtractToRef(origin, V);
V.normalize();
let denom = Vector3.Dot(V, n);
let t = -(Vector3.Dot(origin, n) + d) / denom;
// P = P0 + t*V
let scaledV = V.scaleInPlace(t);
origin.addToRef(scaledV, result);
}
/**
* Returns true if the current Vector3 and the given vector coordinates are strictly equal
* @param otherVector defines the second operand
* @returns true if both vectors are equals
*/
public equals(otherVector: DeepImmutable<Vector3>): boolean {
return otherVector && this._x === otherVector._x && this._y === otherVector._y && this._z === otherVector._z;
}
/**
* Returns true if the current Vector3 and the given vector coordinates are distant less than epsilon
* @param otherVector defines the second operand
* @param epsilon defines the minimal distance to define values as equals
* @returns true if both vectors are distant less than epsilon
*/
public equalsWithEpsilon(otherVector: DeepImmutable<Vector3>, epsilon: number = Epsilon): boolean {
return otherVector && Scalar.WithinEpsilon(this._x, otherVector._x, epsilon) && Scalar.WithinEpsilon(this._y, otherVector._y, epsilon) && Scalar.WithinEpsilon(this._z, otherVector._z, epsilon);
}
/**
* Returns true if the current Vector3 coordinates equals the given floats
* @param x defines the x coordinate of the operand
* @param y defines the y coordinate of the operand
* @param z defines the z coordinate of the operand
* @returns true if both vectors are equals
*/
public equalsToFloats(x: number, y: number, z: number): boolean {
return this._x === x && this._y === y && this._z === z;
}
/**
* Multiplies the current Vector3 coordinates by the given ones
* @param otherVector defines the second operand
* @returns the current updated Vector3
*/
public multiplyInPlace(otherVector: DeepImmutable<Vector3>): Vector3 {
this.x *= otherVector._x;
this.y *= otherVector._y;
this.z *= otherVector._z;
return this;
}
/**
* Returns a new Vector3, result of the multiplication of the current Vector3 by the given vector
* @param otherVector defines the second operand
* @returns the new Vector3
*/
public multiply(otherVector: DeepImmutable<Vector3>): Vector3 {
return this.multiplyByFloats(otherVector._x, otherVector._y, otherVector._z);
}
/**
* Multiplies the current Vector3 by the given one and stores the result in the given vector "result"
* @param otherVector defines the second operand
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
*/
public multiplyToRef(otherVector: DeepImmutable<Vector3>, result: Vector3): Vector3 {
return result.copyFromFloats(this._x * otherVector._x, this._y * otherVector._y, this._z * otherVector._z);
}
/**
* Returns a new Vector3 set with the result of the mulliplication of the current Vector3 coordinates by the given floats
* @param x defines the x coordinate of the operand
* @param y defines the y coordinate of the operand
* @param z defines the z coordinate of the operand
* @returns the new Vector3
*/
public multiplyByFloats(x: number, y: number, z: number): Vector3 {
return new Vector3(this._x * x, this._y * y, this._z * z);
}
/**
* Returns a new Vector3 set with the result of the division of the current Vector3 coordinates by the given ones
* @param otherVector defines the second operand
* @returns the new Vector3
*/
public divide(otherVector: DeepImmutable<Vector3>): Vector3 {
return new Vector3(this._x / otherVector._x, this._y / otherVector._y, this._z / otherVector._z);
}
/**
* Divides the current Vector3 coordinates by the given ones and stores the result in the given vector "result"
* @param otherVector defines the second operand
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
*/
public divideToRef(otherVector: DeepImmutable<Vector3>, result: Vector3): Vector3 {
return result.copyFromFloats(this._x / otherVector._x, this._y / otherVector._y, this._z / otherVector._z);
}
/**
* Divides the current Vector3 coordinates by the given ones.
* @param otherVector defines the second operand
* @returns the current updated Vector3
*/
public divideInPlace(otherVector: Vector3): Vector3 {
return this.divideToRef(otherVector, this);
}
/**
* Updates the current Vector3 with the minimal coordinate values between its and the given vector ones
* @param other defines the second operand
* @returns the current updated Vector3
*/
public minimizeInPlace(other: DeepImmutable<Vector3>): Vector3 {
return this.minimizeInPlaceFromFloats(other._x, other._y, other._z);
}
/**
* Updates the current Vector3 with the maximal coordinate values between its and the given vector ones.
* @param other defines the second operand
* @returns the current updated Vector3
*/
public maximizeInPlace(other: DeepImmutable<Vector3>): Vector3 {
return this.maximizeInPlaceFromFloats(other._x, other._y, other._z);
}
/**
* Updates the current Vector3 with the minimal coordinate values between its and the given coordinates
* @param x defines the x coordinate of the operand
* @param y defines the y coordinate of the operand
* @param z defines the z coordinate of the operand
* @returns the current updated Vector3
*/
public minimizeInPlaceFromFloats(x: number, y: number, z: number): Vector3 {
if (x < this._x) { this.x = x; }
if (y < this._y) { this.y = y; }
if (z < this._z) { this.z = z; }
return this;
}
/**
* Updates the current Vector3 with the maximal coordinate values between its and the given coordinates.
* @param x defines the x coordinate of the operand
* @param y defines the y coordinate of the operand
* @param z defines the z coordinate of the operand
* @returns the current updated Vector3
*/
public maximizeInPlaceFromFloats(x: number, y: number, z: number): Vector3 {
if (x > this._x) { this.x = x; }
if (y > this._y) { this.y = y; }
if (z > this._z) { this.z = z; }
return this;
}
/**
* Due to float precision, scale of a mesh could be uniform but float values are off by a small fraction
* Check if is non uniform within a certain amount of decimal places to account for this
* @param epsilon the amount the values can differ
* @returns if the the vector is non uniform to a certain number of decimal places
*/
public isNonUniformWithinEpsilon(epsilon: number) {
let absX = Math.abs(this._x);
let absY = Math.abs(this._y);
if (!Scalar.WithinEpsilon(absX, absY, epsilon)) {
return true;
}
let absZ = Math.abs(this._z);
if (!Scalar.WithinEpsilon(absX, absZ, epsilon)) {
return true;
}
if (!Scalar.WithinEpsilon(absY, absZ, epsilon)) {
return true;
}
return false;
}
/**
* Gets a boolean indicating that the vector is non uniform meaning x, y or z are not all the same
*/
public get isNonUniform(): boolean {
let absX = Math.abs(this._x);
let absY = Math.abs(this._y);
if (absX !== absY) {
return true;
}
let absZ = Math.abs(this._z);
if (absX !== absZ) {
return true;
}
return false;
}
/**
* Gets a new Vector3 from current Vector3 floored values
* @returns a new Vector3
*/
public floor(): Vector3 {
return new Vector3(Math.floor(this._x), Math.floor(this._y), Math.floor(this._z));
}
/**
* Gets a new Vector3 from current Vector3 floored values
* @returns a new Vector3
*/
public fract(): Vector3 {
return new Vector3(this._x - Math.floor(this._x), this._y - Math.floor(this._y), this._z - Math.floor(this._z));
}
// Properties
/**
* Gets the length of the Vector3
* @returns the length of the Vector3
*/
public length(): number {
return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z);
}
/**
* Gets the squared length of the Vector3
* @returns squared length of the Vector3
*/
public lengthSquared(): number {
return (this._x * this._x + this._y * this._y + this._z * this._z);
}
/**
* Normalize the current Vector3.
* Please note that this is an in place operation.
* @returns the current updated Vector3
*/
public normalize(): Vector3 {
return this.normalizeFromLength(this.length());
}
/**
* Reorders the x y z properties of the vector in place
* @param order new ordering of the properties (eg. for vector 1,2,3 with "ZYX" will produce 3,2,1)
* @returns the current updated vector
*/
public reorderInPlace(order: string) {
order = order.toLowerCase();
if (order === "xyz") {
return this;
}
MathTmp.Vector3[0].copyFrom(this);
["x", "y", "z"].forEach((val, i) => {
(<any>this)[val] = (<any>MathTmp.Vector3[0])[order[i]];
});
return this;
}
/**
* Rotates the vector around 0,0,0 by a quaternion
* @param quaternion the rotation quaternion
* @param result vector to store the result
* @returns the resulting vector
*/
public rotateByQuaternionToRef(quaternion: Quaternion, result: Vector3) {
quaternion.toRotationMatrix(MathTmp.Matrix[0]);
Vector3.TransformCoordinatesToRef(this, MathTmp.Matrix[0], result);
return result;
}
/**
* Rotates a vector around a given point
* @param quaternion the rotation quaternion
* @param point the point to rotate around
* @param result vector to store the result
* @returns the resulting vector
*/
public rotateByQuaternionAroundPointToRef(quaternion: Quaternion, point: Vector3, result: Vector3) {
this.subtractToRef(point, MathTmp.Vector3[0]);
MathTmp.Vector3[0].rotateByQuaternionToRef(quaternion, MathTmp.Vector3[0]);
point.addToRef(MathTmp.Vector3[0], result);
return result;
}
/**
* Returns a new Vector3 as the cross product of the current vector and the "other" one
* The cross product is then orthogonal to both current and "other"
* @param other defines the right operand
* @returns the cross product
*/
public cross(other: Vector3) {
return Vector3.Cross(this, other);
}
/**
* Normalize the current Vector3 with the given input length.
* Please note that this is an in place operation.
* @param len the length of the vector
* @returns the current updated Vector3
*/
public normalizeFromLength(len: number): Vector3 {
if (len === 0 || len === 1.0) {
return this;
}
return this.scaleInPlace(1.0 / len);
}
/**
* Normalize the current Vector3 to a new vector
* @returns the new Vector3
*/
public normalizeToNew(): Vector3 {
const normalized = new Vector3(0, 0, 0);
this.normalizeToRef(normalized);
return normalized;
}
/**
* Normalize the current Vector3 to the reference
* @param reference define the Vector3 to update
* @returns the updated Vector3
*/
public normalizeToRef(reference: Vector3): Vector3 {
var len = this.length();
if (len === 0 || len === 1.0) {
return reference.copyFromFloats(this._x, this._y, this._z);
}
return this.scaleToRef(1.0 / len, reference);
}
/**
* Creates a new Vector3 copied from the current Vector3
* @returns the new Vector3
*/
public clone(): Vector3 {
return new Vector3(this._x, this._y, this._z);
}
/**
* Copies the given vector coordinates to the current Vector3 ones
* @param source defines the source Vector3
* @returns the current updated Vector3
*/
public copyFrom(source: DeepImmutable<Vector3>): Vector3 {
return this.copyFromFloats(source._x, source._y, source._z);
}
/**
* Copies the given floats to the current Vector3 coordinates
* @param x defines the x coordinate of the operand
* @param y defines the y coordinate of the operand
* @param z defines the z coordinate of the operand
* @returns the current updated Vector3
*/
public copyFromFloats(x: number, y: number, z: number): Vector3 {
this.x = x;
this.y = y;
this.z = z;
return this;
}
/**
* Copies the given floats to the current Vector3 coordinates
* @param x defines the x coordinate of the operand
* @param y defines the y coordinate of the operand
* @param z defines the z coordinate of the operand
* @returns the current updated Vector3
*/
public set(x: number, y: number, z: number): Vector3 {
return this.copyFromFloats(x, y, z);
}
/**
* Copies the given float to the current Vector3 coordinates
* @param v defines the x, y and z coordinates of the operand
* @returns the current updated Vector3
*/
public setAll(v: number): Vector3 {
this.x = this.y = this.z = v;
return this;
}
// Statics
/**
* Get the clip factor between two vectors
* @param vector0 defines the first operand
* @param vector1 defines the second operand
* @param axis defines the axis to use
* @param size defines the size along the axis
* @returns the clip factor
*/
public static GetClipFactor(vector0: DeepImmutable<Vector3>, vector1: DeepImmutable<Vector3>, axis: DeepImmutable<Vector3>, size: number) {
var d0 = Vector3.Dot(vector0, axis) - size;
var d1 = Vector3.Dot(vector1, axis) - size;
var s = d0 / (d0 - d1);
return s;
}
/**
* Get angle between two vectors
* @param vector0 angle between vector0 and vector1
* @param vector1 angle between vector0 and vector1
* @param normal direction of the normal
* @return the angle between vector0 and vector1
*/
public static GetAngleBetweenVectors(vector0: DeepImmutable<Vector3>, vector1: DeepImmutable<Vector3>, normal: DeepImmutable<Vector3>): number {
const v0: Vector3 = vector0.normalizeToRef(MathTmp.Vector3[1]);
const v1: Vector3 = vector1.normalizeToRef(MathTmp.Vector3[2]);
const dot: number = Vector3.Dot(v0, v1);
const n = MathTmp.Vector3[3];
Vector3.CrossToRef(v0, v1, n);
if (Vector3.Dot(n, normal) > 0) {
return Math.acos(dot);
}
return -Math.acos(dot);
}
/**
* Returns a new Vector3 set from the index "offset" of the given array
* @param array defines the source array
* @param offset defines the offset in the source array
* @returns the new Vector3
*/
public static FromArray(array: DeepImmutable<ArrayLike<number>>, offset: number = 0): Vector3 {
return new Vector3(array[offset], array[offset + 1], array[offset + 2]);
}
/**
* Returns a new Vector3 set from the index "offset" of the given Float32Array
* @param array defines the source array
* @param offset defines the offset in the source array
* @returns the new Vector3
* @deprecated Please use FromArray instead.
*/
public static FromFloatArray(array: DeepImmutable<Float32Array>, offset?: number): Vector3 {
return Vector3.FromArray(array, offset);
}
/**
* Sets the given vector "result" with the element values from the index "offset" of the given array
* @param array defines the source array
* @param offset defines the offset in the source array
* @param result defines the Vector3 where to store the result
*/
public static FromArrayToRef(array: DeepImmutable<ArrayLike<number>>, offset: number, result: Vector3): void {
result.x = array[offset];
result.y = array[offset + 1];
result.z = array[offset + 2];
}
/**
* Sets the given vector "result" with the element values from the index "offset" of the given Float32Array
* @param array defines the source array
* @param offset defines the offset in the source array
* @param result defines the Vector3 where to store the result
* @deprecated Please use FromArrayToRef instead.
*/
public static FromFloatArrayToRef(array: DeepImmutable<Float32Array>, offset: number, result: Vector3): void {
return Vector3.FromArrayToRef(array, offset, result);
}
/**
* Sets the given vector "result" with the given floats.
* @param x defines the x coordinate of the source
* @param y defines the y coordinate of the source
* @param z defines the z coordinate of the source
* @param result defines the Vector3 where to store the result
*/
public static FromFloatsToRef(x: number, y: number, z: number, result: Vector3): void {
result.copyFromFloats(x, y, z);
}
/**
* Returns a new Vector3 set to (0.0, 0.0, 0.0)
* @returns a new empty Vector3
*/
public static Zero(): Vector3 {
return new Vector3(0.0, 0.0, 0.0);
}
/**
* Returns a new Vector3 set to (1.0, 1.0, 1.0)
* @returns a new unit Vector3
*/
public static One(): Vector3 {
return new Vector3(1.0, 1.0, 1.0);
}
/**
* Returns a new Vector3 set to (0.0, 1.0, 0.0)
* @returns a new up Vector3
*/
public static Up(): Vector3 {
return new Vector3(0.0, 1.0, 0.0);
}
/**
* Gets a up Vector3 that must not be updated
*/
public static get UpReadOnly(): DeepImmutable<Vector3> {
return Vector3._UpReadOnly;
}
/**
* Gets a zero Vector3 that must not be updated
*/
public static get ZeroReadOnly(): DeepImmutable<Vector3> {
return Vector3._ZeroReadOnly;
}
/**
* Returns a new Vector3 set to (0.0, -1.0, 0.0)
* @returns a new down Vector3
*/
public static Down(): Vector3 {
return new Vector3(0.0, -1.0, 0.0);
}
/**
* Returns a new Vector3 set to (0.0, 0.0, 1.0)
* @param rightHandedSystem is the scene right-handed (negative z)
* @returns a new forward Vector3
*/
public static Forward(rightHandedSystem: boolean = false): Vector3 {
return new Vector3(0.0, 0.0, (rightHandedSystem ? -1.0 : 1.0));
}
/**
* Returns a new Vector3 set to (0.0, 0.0, -1.0)
* @param rightHandedSystem is the scene right-handed (negative-z)
* @returns a new forward Vector3
*/
public static Backward(rightHandedSystem: boolean = false): Vector3 {
return new Vector3(0.0, 0.0, (rightHandedSystem ? 1.0 : -1.0));
}
/**
* Returns a new Vector3 set to (1.0, 0.0, 0.0)
* @returns a new right Vector3
*/
public static Right(): Vector3 {
return new Vector3(1.0, 0.0, 0.0);
}
/**
* Returns a new Vector3 set to (-1.0, 0.0, 0.0)
* @returns a new left Vector3
*/
public static Left(): Vector3 {
return new Vector3(-1.0, 0.0, 0.0);
}
/**
* Returns a new Vector3 set with the result of the transformation by the given matrix of the given vector.
* This method computes tranformed coordinates only, not transformed direction vectors (ie. it takes translation in account)
* @param vector defines the Vector3 to transform
* @param transformation defines the transformation matrix
* @returns the transformed Vector3
*/
public static TransformCoordinates(vector: DeepImmutable<Vector3>, transformation: DeepImmutable<Matrix>): Vector3 {
var result = Vector3.Zero();
Vector3.TransformCoordinatesToRef(vector, transformation, result);
return result;
}
/**
* Sets the given vector "result" coordinates with the result of the transformation by the given matrix of the given vector
* This method computes tranformed coordinates only, not transformed direction vectors (ie. it takes translation in account)
* @param vector defines the Vector3 to transform
* @param transformation defines the transformation matrix
* @param result defines the Vector3 where to store the result
*/
public static TransformCoordinatesToRef(vector: DeepImmutable<Vector3>, transformation: DeepImmutable<Matrix>, result: Vector3): void {
Vector3.TransformCoordinatesFromFloatsToRef(vector._x, vector._y, vector._z, transformation, result);
}
/**
* Sets the given vector "result" coordinates with the result of the transformation by the given matrix of the given floats (x, y, z)
* This method computes tranformed coordinates only, not transformed direction vectors
* @param x define the x coordinate of the source vector
* @param y define the y coordinate of the source vector
* @param z define the z coordinate of the source vector
* @param transformation defines the transformation matrix
* @param result defines the Vector3 where to store the result
*/
public static TransformCoordinatesFromFloatsToRef(x: number, y: number, z: number, transformation: DeepImmutable<Matrix>, result: Vector3): void {
const m = transformation.m;
var rx = x * m[0] + y * m[4] + z * m[8] + m[12];
var ry = x * m[1] + y * m[5] + z * m[9] + m[13];
var rz = x * m[2] + y * m[6] + z * m[10] + m[14];
var rw = 1 / (x * m[3] + y * m[7] + z * m[11] + m[15]);
result.x = rx * rw;
result.y = ry * rw;
result.z = rz * rw;
}
/**
* Returns a new Vector3 set with the result of the normal transformation by the given matrix of the given vector
* This methods computes transformed normalized direction vectors only (ie. it does not apply translation)
* @param vector defines the Vector3 to transform
* @param transformation defines the transformation matrix
* @returns the new Vector3
*/
public static TransformNormal(vector: DeepImmutable<Vector3>, transformation: DeepImmutable<Matrix>): Vector3 {
var result = Vector3.Zero();
Vector3.TransformNormalToRef(vector, transformation, result);
return result;
}
/**
* Sets the given vector "result" with the result of the normal transformation by the given matrix of the given vector
* This methods computes transformed normalized direction vectors only (ie. it does not apply translation)
* @param vector defines the Vector3 to transform
* @param transformation defines the transformation matrix
* @param result defines the Vector3 where to store the result
*/
public static TransformNormalToRef(vector: DeepImmutable<Vector3>, transformation: DeepImmutable<Matrix>, result: Vector3): void {
this.TransformNormalFromFloatsToRef(vector._x, vector._y, vector._z, transformation, result);
}
/**
* Sets the given vector "result" with the result of the normal transformation by the given matrix of the given floats (x, y, z)
* This methods computes transformed normalized direction vectors only (ie. it does not apply translation)
* @param x define the x coordinate of the source vector
* @param y define the y coordinate of the source vector
* @param z define the z coordinate of the source vector
* @param transformation defines the transformation matrix
* @param result defines the Vector3 where to store the result
*/
public static TransformNormalFromFloatsToRef(x: number, y: number, z: number, transformation: DeepImmutable<Matrix>, result: Vector3): void {
const m = transformation.m;
result.x = x * m[0] + y * m[4] + z * m[8];
result.y = x * m[1] + y * m[5] + z * m[9];
result.z = x * m[2] + y * m[6] + z * m[10];
}
/**
* Returns a new Vector3 located for "amount" on the CatmullRom interpolation spline defined by the vectors "value1", "value2", "value3", "value4"
* @param value1 defines the first control point
* @param value2 defines the second control point
* @param value3 defines the third control point
* @param value4 defines the fourth control point
* @param amount defines the amount on the spline to use
* @returns the new Vector3
*/
public static CatmullRom(value1: DeepImmutable<Vector3>, value2: DeepImmutable<Vector3>, value3: DeepImmutable<Vector3>, value4: DeepImmutable<Vector3>, amount: number): Vector3 {
var squared = amount * amount;
var cubed = amount * squared;
var x = 0.5 * ((((2.0 * value2._x) + ((-value1._x + value3._x) * amount)) +
(((((2.0 * value1._x) - (5.0 * value2._x)) + (4.0 * value3._x)) - value4._x) * squared)) +
((((-value1._x + (3.0 * value2._x)) - (3.0 * value3._x)) + value4._x) * cubed));
var y = 0.5 * ((((2.0 * value2._y) + ((-value1._y + value3._y) * amount)) +
(((((2.0 * value1._y) - (5.0 * value2._y)) + (4.0 * value3._y)) - value4._y) * squared)) +
((((-value1._y + (3.0 * value2._y)) - (3.0 * value3._y)) + value4._y) * cubed));
var z = 0.5 * ((((2.0 * value2._z) + ((-value1._z + value3._z) * amount)) +
(((((2.0 * value1._z) - (5.0 * value2._z)) + (4.0 * value3._z)) - value4._z) * squared)) +
((((-value1._z + (3.0 * value2._z)) - (3.0 * value3._z)) + value4._z) * cubed));
return new Vector3(x, y, z);
}
/**
* Returns a new Vector3 set with the coordinates of "value", if the vector "value" is in the cube defined by the vectors "min" and "max"
* If a coordinate value of "value" is lower than one of the "min" coordinate, then this "value" coordinate is set with the "min" one
* If a coordinate value of "value" is greater than one of the "max" coordinate, then this "value" coordinate is set with the "max" one
* @param value defines the current value
* @param min defines the lower range value
* @param max defines the upper range value
* @returns the new Vector3
*/
public static Clamp(value: DeepImmutable<Vector3>, min: DeepImmutable<Vector3>, max: DeepImmutable<Vector3>): Vector3 {
const v = new Vector3();
Vector3.ClampToRef(value, min, max, v);
return v;
}
/**
* Sets the given vector "result" with the coordinates of "value", if the vector "value" is in the cube defined by the vectors "min" and "max"
* If a coordinate value of "value" is lower than one of the "min" coordinate, then this "value" coordinate is set with the "min" one
* If a coordinate value of "value" is greater than one of the "max" coordinate, then this "value" coordinate is set with the "max" one
* @param value defines the current value
* @param min defines the lower range value
* @param max defines the upper range value
* @param result defines the Vector3 where to store the result
*/
public static ClampToRef(value: DeepImmutable<Vector3>, min: DeepImmutable<Vector3>, max: DeepImmutable<Vector3>, result: Vector3): void {
var x = value._x;
x = (x > max._x) ? max._x : x;
x = (x < min._x) ? min._x : x;
var y = value._y;
y = (y > max._y) ? max._y : y;
y = (y < min._y) ? min._y : y;
var z = value._z;
z = (z > max._z) ? max._z : z;
z = (z < min._z) ? min._z : z;
result.copyFromFloats(x, y, z);
}
/**
* Checks if a given vector is inside a specific range
* @param v defines the vector to test
* @param min defines the minimum range
* @param max defines the maximum range
*/
public static CheckExtends(v: Vector3, min: Vector3, max: Vector3): void {
min.minimizeInPlace(v);
max.maximizeInPlace(v);
}
/**
* Returns a new Vector3 located for "amount" (float) on the Hermite interpolation spline defined by the vectors "value1", "tangent1", "value2", "tangent2"
* @param value1 defines the first control point
* @param tangent1 defines the first tangent vector
* @param value2 defines the second control point
* @param tangent2 defines the second tangent vector
* @param amount defines the amount on the interpolation spline (between 0 and 1)
* @returns the new Vector3
*/
public static Hermite(value1: DeepImmutable<Vector3>, tangent1: DeepImmutable<Vector3>, value2: DeepImmutable<Vector3>, tangent2: DeepImmutable<Vector3>, amount: number): Vector3 {
var squared = amount * amount;
var cubed = amount * squared;
var part1 = ((2.0 * cubed) - (3.0 * squared)) + 1.0;
var part2 = (-2.0 * cubed) + (3.0 * squared);
var part3 = (cubed - (2.0 * squared)) + amount;
var part4 = cubed - squared;
var x = (((value1._x * part1) + (value2._x * part2)) + (tangent1._x * part3)) + (tangent2._x * part4);
var y = (((value1._y * part1) + (value2._y * part2)) + (tangent1._y * part3)) + (tangent2._y * part4);
var z = (((value1._z * part1) + (value2._z * part2)) + (tangent1._z * part3)) + (tangent2._z * part4);
return new Vector3(x, y, z);
}
/**
* Returns a new Vector3 located for "amount" (float) on the linear interpolation between the vectors "start" and "end"
* @param start defines the start value
* @param end defines the end value
* @param amount max defines amount between both (between 0 and 1)
* @returns the new Vector3
*/
public static Lerp(start: DeepImmutable<Vector3>, end: DeepImmutable<Vector3>, amount: number): Vector3 {
var result = new Vector3(0, 0, 0);
Vector3.LerpToRef(start, end, amount, result);
return result;
}
/**
* Sets the given vector "result" with the result of the linear interpolation from the vector "start" for "amount" to the vector "end"
* @param start defines the start value
* @param end defines the end value
* @param amount max defines amount between both (between 0 and 1)
* @param result defines the Vector3 where to store the result
*/
public static LerpToRef(start: DeepImmutable<Vector3>, end: DeepImmutable<Vector3>, amount: number, result: Vector3): void {
result.x = start._x + ((end._x - start._x) * amount);
result.y = start._y + ((end._y - start._y) * amount);
result.z = start._z + ((end._z - start._z) * amount);
}
/**
* Returns the dot product (float) between the vectors "left" and "right"
* @param left defines the left operand
* @param right defines the right operand
* @returns the dot product
*/
public static Dot(left: DeepImmutable<Vector3>, right: DeepImmutable<Vector3>): number {
return (left._x * right._x + left._y * right._y + left._z * right._z);
}
/**
* Returns a new Vector3 as the cross product of the vectors "left" and "right"
* The cross product is then orthogonal to both "left" and "right"
* @param left defines the left operand
* @param right defines the right operand
* @returns the cross product
*/
public static Cross(left: DeepImmutable<Vector3>, right: DeepImmutable<Vector3>): Vector3 {
var result = Vector3.Zero();
Vector3.CrossToRef(left, right, result);
return result;
}
/**
* Sets the given vector "result" with the cross product of "left" and "right"
* The cross product is then orthogonal to both "left" and "right"
* @param left defines the left operand
* @param right defines the right operand
* @param result defines the Vector3 where to store the result
*/
public static CrossToRef(left: DeepImmutable<Vector3>, right: DeepImmutable<Vector3>, result: Vector3): void {
const x = left._y * right._z - left._z * right._y;
const y = left._z * right._x - left._x * right._z;
const z = left._x * right._y - left._y * right._x;
result.copyFromFloats(x, y, z);
}
/**
* Returns a new Vector3 as the normalization of the given vector
* @param vector defines the Vector3 to normalize
* @returns the new Vector3
*/
public static Normalize(vector: DeepImmutable<Vector3>): Vector3 {
var result = Vector3.Zero();
Vector3.NormalizeToRef(vector, result);
return result;
}
/**
* Sets the given vector "result" with the normalization of the given first vector
* @param vector defines the Vector3 to normalize
* @param result defines the Vector3 where to store the result
*/
public static NormalizeToRef(vector: DeepImmutable<Vector3>, result: Vector3): void {
vector.normalizeToRef(result);
}
/**
* Project a Vector3 onto screen space
* @param vector defines the Vector3 to project
* @param world defines the world matrix to use
* @param transform defines the transform (view x projection) matrix to use
* @param viewport defines the screen viewport to use
* @returns the new Vector3
*/
public static Project(vector: DeepImmutable<Vector3>, world: DeepImmutable<Matrix>, transform: DeepImmutable<Matrix>, viewport: DeepImmutable<Viewport>): Vector3 {
var cw = viewport.width;
var ch = viewport.height;
var cx = viewport.x;
var cy = viewport.y;
var viewportMatrix = MathTmp.Matrix[1];
Matrix.FromValuesToRef(
cw / 2.0, 0, 0, 0,
0, -ch / 2.0, 0, 0,
0, 0, 0.5, 0,
cx + cw / 2.0, ch / 2.0 + cy, 0.5, 1, viewportMatrix);
var matrix = MathTmp.Matrix[0];
world.multiplyToRef(transform, matrix);
matrix.multiplyToRef(viewportMatrix, matrix);
return Vector3.TransformCoordinates(vector, matrix);
}
/** @hidden */
public static _UnprojectFromInvertedMatrixToRef(source: DeepImmutable<Vector3>, matrix: DeepImmutable<Matrix>, result: Vector3) {
Vector3.TransformCoordinatesToRef(source, matrix, result);
const m = matrix.m;
var num = source._x * m[3] + source._y * m[7] + source._z * m[11] + m[15];
if (Scalar.WithinEpsilon(num, 1.0)) {
result.scaleInPlace(1.0 / num);
}
}
/**
* Unproject from screen space to object space
* @param source defines the screen space Vector3 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 transform defines the transform (view x projection) matrix to use
* @returns the new Vector3
*/
public static UnprojectFromTransform(source: Vector3, viewportWidth: number, viewportHeight: number, world: DeepImmutable<Matrix>, transform: DeepImmutable<Matrix>): Vector3 {
var matrix = MathTmp.Matrix[0];
world.multiplyToRef(transform, matrix);
matrix.invert();
source.x = source._x / viewportWidth * 2 - 1;
source.y = -(source._y / viewportHeight * 2 - 1);
const vector = new Vector3();
Vector3._UnprojectFromInvertedMatrixToRef(source, matrix, vector);
return vector;
}
/**
* Unproject from screen space to object space
* @param source defines the screen space Vector3 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
* @returns the new Vector3
*/
public static Unproject(source: DeepImmutable<Vector3>, viewportWidth: number, viewportHeight: number, world: DeepImmutable<Matrix>, view: DeepImmutable<Matrix>, projection: DeepImmutable<Matrix>): Vector3 {
let result = Vector3.Zero();
Vector3.UnprojectToRef(source, viewportWidth, viewportHeight, world, view, projection, result);
return result;
}
/**
* Unproject from screen space to object space
* @param source defines the screen space Vector3 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
* @param result defines the Vector3 where to store the result
*/
public static UnprojectToRef(source: DeepImmutable<Vector3>, viewportWidth: number, viewportHeight: number, world: DeepImmutable<Matrix>, view: DeepImmutable<Matrix>, projection: DeepImmutable<Matrix>, result: Vector3): void {
Vector3.UnprojectFloatsToRef(source._x, source._y, source._z, viewportWidth, viewportHeight, world, view, projection, result);
}
/**
* Unproject 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 sourceZ defines the screen space z 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
* @param result defines the Vector3 where to store the result
*/
public static UnprojectFloatsToRef(sourceX: float, sourceY: float, sourceZ: float, viewportWidth: number, viewportHeight: number, world: DeepImmutable<Matrix>, view: DeepImmutable<Matrix>, projection: DeepImmutable<Matrix>, result: Vector3): void {
var matrix = MathTmp.Matrix[0];
world.multiplyToRef(view, matrix);
matrix.multiplyToRef(projection, matrix);
matrix.invert();
var screenSource = MathTmp.Vector3[0];
screenSource.x = sourceX / viewportWidth * 2 - 1;
screenSource.y = -(sourceY / viewportHeight * 2 - 1);
screenSource.z = 2 * sourceZ - 1.0;
Vector3._UnprojectFromInvertedMatrixToRef(screenSource, matrix, result);
}
/**
* Gets the minimal coordinate values between two Vector3
* @param left defines the first operand
* @param right defines the second operand
* @returns the new Vector3
*/
public static Minimize(left: DeepImmutable<Vector3>, right: DeepImmutable<Vector3>): Vector3 {
var min = left.clone();
min.minimizeInPlace(right);
return min;
}
/**
* Gets the maximal coordinate values between two Vector3
* @param left defines the first operand
* @param right defines the second operand
* @returns the new Vector3
*/
public static Maximize(left: DeepImmutable<Vector3>, right: DeepImmutable<Vector3>): Vector3 {
var max = left.clone();
max.maximizeInPlace(right);
return max;
}
/**
* Returns the distance between the vectors "value1" and "value2"
* @param value1 defines the first operand
* @param value2 defines the second operand
* @returns the distance
*/
public static Distance(value1: DeepImmutable<Vector3>, value2: DeepImmutable<Vector3>): number {
return Math.sqrt(Vector3.DistanceSquared(value1, value2));
}
/**
* Returns the squared distance between the vectors "value1" and "value2"
* @param value1 defines the first operand
* @param value2 defines the second operand
* @returns the squared distance
*/
public static DistanceSquared(value1: DeepImmutable<Vector3>, value2: DeepImmutable<Vector3>): number {
var x = value1._x - value2._x;
var y = value1._y - value2._y;
var z = value1._z - value2._z;
return (x * x) + (y * y) + (z * z);
}
/**
* Returns a new Vector3 located at the center between "value1" and "value2"
* @param value1 defines the first operand
* @param value2 defines the second operand
* @returns the new Vector3
*/
public static Center(value1: DeepImmutable<Vector3>, value2: DeepImmutable<Vector3>): Vector3 {
var center = value1.add(value2);
center.scaleInPlace(0.5);
return center;
}
/**
* Given three orthogonal normalized left-handed oriented Vector3 axis in space (target system),
* RotationFromAxis() returns the rotation Euler angles (ex : rotation.x, rotation.y, rotation.z) to apply
* to something in order to rotate it from its local system to the given target system
* Note: axis1, axis2 and axis3 are normalized during this operation
* @param axis1 defines the first axis
* @param axis2 defines the second axis
* @param axis3 defines the third axis
* @returns a new Vector3
*/
public static RotationFromAxis(axis1: DeepImmutable<Vector3>, axis2: DeepImmutable<Vector3>, axis3: DeepImmutable<Vector3>): Vector3 {
var rotation = Vector3.Zero();
Vector3.RotationFromAxisToRef(axis1, axis2, axis3, rotation);
return rotation;
}
/**
* The same than RotationFromAxis but updates the given ref Vector3 parameter instead of returning a new Vector3
* @param axis1 defines the first axis
* @param axis2 defines the second axis
* @param axis3 defines the third axis
* @param ref defines the Vector3 where to store the result
*/
public static RotationFromAxisToRef(axis1: DeepImmutable<Vector3>, axis2: DeepImmutable<Vector3>, axis3: DeepImmutable<Vector3>, ref: Vector3): void {
var quat = MathTmp.Quaternion[0];
Quaternion.RotationQuaternionFromAxisToRef(axis1, axis2, axis3, quat);
quat.toEulerAnglesToRef(ref);
}
}
/**
* Vector4 class created for EulerAngle class conversion to Quaternion
*/
export class Vector4 {
/**
* Creates a Vector4 object from the given floats.
* @param x x value of the vector
* @param y y value of the vector
* @param z z value of the vector
* @param w w value of the vector
*/
constructor(
/** x value of the vector */
public x: number,
/** y value of the vector */
public y: number,
/** z value of the vector */
public z: number,
/** w value of the vector */
public w: number
) { }
/**
* Returns the string with the Vector4 coordinates.
* @returns a string containing all the vector values
*/
public toString(): string {
return "{X: " + this.x + " Y:" + this.y + " Z:" + this.z + " W:" + this.w + "}";
}
/**
* Returns the string "Vector4".
* @returns "Vector4"
*/
public getClassName(): string {
return "Vector4";
}
/**
* Returns the Vector4 hash code.
* @returns a unique hash code
*/
public getHashCode(): number {
let hash = this.x | 0;
hash = (hash * 397) ^ (this.y | 0);
hash = (hash * 397) ^ (this.z | 0);
hash = (hash * 397) ^ (this.w | 0);
return hash;
}
// Operators
/**
* Returns a new array populated with 4 elements : the Vector4 coordinates.
* @returns the resulting array
*/
public asArray(): number[] {
var result = new Array<number>();
this.toArray(result, 0);
return result;
}
/**
* Populates the given array from the given index with the Vector4 coordinates.
* @param array array to populate
* @param index index of the array to start at (default: 0)
* @returns the Vector4.
*/
public toArray(array: FloatArray, index?: number): Vector4 {
if (index === undefined) {
index = 0;
}
array[index] = this.x;
array[index + 1] = this.y;
array[index + 2] = this.z;
array[index + 3] = this.w;
return this;
}
/**
* Update the current vector from an array
* @param array defines the destination array
* @param index defines the offset in the destination array
* @returns the current Vector3
*/
public fromArray(array: FloatArray, index: number = 0): Vector4 {
Vector4.FromArrayToRef(array, index, this);
return this;
}
/**
* Adds the given vector to the current Vector4.
* @param otherVector the vector to add
* @returns the updated Vector4.
*/
public addInPlace(otherVector: DeepImmutable<Vector4>): Vector4 {
this.x += otherVector.x;
this.y += otherVector.y;
this.z += otherVector.z;
this.w += otherVector.w;
return this;
}
/**
* Returns a new Vector4 as the result of the addition of the current Vector4 and the given one.
* @param otherVector the vector to add
* @returns the resulting vector
*/
public add(otherVector: DeepImmutable<Vector4>): Vector4 {
return new Vector4(this.x + otherVector.x, this.y + otherVector.y, this.z + otherVector.z, this.w + otherVector.w);
}
/**
* Updates the given vector "result" with the result of the addition of the current Vector4 and the given one.
* @param otherVector the vector to add
* @param result the vector to store the result
* @returns the current Vector4.
*/
public addToRef(otherVector: DeepImmutable<Vector4>, result: Vector4): Vector4 {
result.x = this.x + otherVector.x;
result.y = this.y + otherVector.y;
result.z = this.z + otherVector.z;
result.w = this.w + otherVector.w;
return this;
}
/**
* Subtract in place the given vector from the current Vector4.
* @param otherVector the vector to subtract
* @returns the updated Vector4.
*/
public subtractInPlace(otherVector: DeepImmutable<Vector4>): Vector4 {
this.x -= otherVector.x;
this.y -= otherVector.y;
this.z -= otherVector.z;
this.w -= otherVector.w;
return this;
}
/**
* Returns a new Vector4 with the result of the subtraction of the given vector from the current Vector4.
* @param otherVector the vector to add
* @returns the new vector with the result
*/
public subtract(otherVector: DeepImmutable<Vector4>): Vector4 {
return new Vector4(this.x - otherVector.x, this.y - otherVector.y, this.z - otherVector.z, this.w - otherVector.w);
}
/**
* Sets the given vector "result" with the result of the subtraction of the given vector from the current Vector4.
* @param otherVector the vector to subtract
* @param result the vector to store the result
* @returns the current Vector4.
*/
public subtractToRef(otherVector: DeepImmutable<Vector4>, result: Vector4): Vector4 {
result.x = this.x - otherVector.x;
result.y = this.y - otherVector.y;
result.z = this.z - otherVector.z;
result.w = this.w - otherVector.w;
return this;
}
/**
* Returns a new Vector4 set with the result of the subtraction of the given floats from the current Vector4 coordinates.
*/
/**
* Returns a new Vector4 set with the result of the subtraction of the given floats from the current Vector4 coordinates.
* @param x value to subtract
* @param y value to subtract
* @param z value to subtract
* @param w value to subtract
* @returns new vector containing the result
*/
public subtractFromFloats(x: number, y: number, z: number, w: number): Vector4 {
return new Vector4(this.x - x, this.y - y, this.z - z, this.w - w);
}
/**
* Sets the given vector "result" set with the result of the subtraction of the given floats from the current Vector4 coordinates.
* @param x value to subtract
* @param y value to subtract
* @param z value to subtract
* @param w value to subtract
* @param result the vector to store the result in
* @returns the current Vector4.
*/
public subtractFromFloatsToRef(x: number, y: number, z: number, w: number, result: Vector4): Vector4 {
result.x = this.x - x;
result.y = this.y - y;
result.z = this.z - z;
result.w = this.w - w;
return this;
}
/**
* Returns a new Vector4 set with the current Vector4 negated coordinates.
* @returns a new vector with the negated values
*/
public negate(): Vector4 {
return new Vector4(-this.x, -this.y, -this.z, -this.w);
}
/**
* Negate this vector in place
* @returns this
*/
public negateInPlace(): Vector4 {
this.x *= -1;
this.y *= -1;
this.z *= -1;
this.w *= -1;
return this;
}
/**
* Negate the current Vector4 and stores the result in the given vector "result" coordinates
* @param result defines the Vector3 object where to store the result
* @returns the current Vector4
*/
public negateToRef(result: Vector4): Vector4 {
return result.copyFromFloats(this.x * -1, this.y * -1, this.z * -1, this.w * -1);
}
/**
* Multiplies the current Vector4 coordinates by scale (float).
* @param scale the number to scale with
* @returns the updated Vector4.
*/
public scaleInPlace(scale: number): Vector4 {
this.x *= scale;
this.y *= scale;
this.z *= scale;
this.w *= scale;
return this;
}
/**
* Returns a new Vector4 set with the current Vector4 coordinates multiplied by scale (float).
* @param scale the number to scale with
* @returns a new vector with the result
*/
public scale(scale: number): Vector4 {
return new Vector4(this.x * scale, this.y * scale, this.z * scale, this.w * scale);
}
/**
* Sets the given vector "result" with the current Vector4 coordinates multiplied by scale (float).
* @param scale the number to scale with
* @param result a vector to store the result in
* @returns the current Vector4.
*/
public scaleToRef(scale: number, result: Vector4): Vector4 {
result.x = this.x * scale;
result.y = this.y * scale;
result.z = this.z * scale;
result.w = this.w * scale;
return this;
}
/**
* Scale the current Vector4 values by a factor and add the result to a given Vector4
* @param scale defines the scale factor
* @param result defines the Vector4 object where to store the result
* @returns the unmodified current Vector4
*/
public scaleAndAddToRef(scale: number, result: Vector4): Vector4 {
result.x += this.x * scale;
result.y += this.y * scale;
result.z += this.z * scale;
result.w += this.w * scale;
return this;
}
/**
* Boolean : True if the current Vector4 coordinates are stricly equal to the given ones.
* @param otherVector the vector to compare against
* @returns true if they are equal
*/
public equals(otherVector: DeepImmutable<Vector4>): boolean {
return otherVector && this.x === otherVector.x && this.y === otherVector.y && this.z === otherVector.z && this.w === otherVector.w;
}
/**
* Boolean : True if the current Vector4 coordinates are each beneath the distance "epsilon" from the given vector ones.
* @param otherVector vector to compare against
* @param epsilon (Default: very small number)
* @returns true if they are equal
*/
public equalsWithEpsilon(otherVector: DeepImmutable<Vector4>, epsilon: number = Epsilon): boolean {
return otherVector
&& Scalar.WithinEpsilon(this.x, otherVector.x, epsilon)
&& Scalar.WithinEpsilon(this.y, otherVector.y, epsilon)
&& Scalar.WithinEpsilon(this.z, otherVector.z, epsilon)
&& Scalar.WithinEpsilon(this.w, otherVector.w, epsilon);
}
/**
* Boolean : True if the given floats are strictly equal to the current Vector4 coordinates.
* @param x x value to compare against
* @param y y value to compare against
* @param z z value to compare against
* @param w w value to compare against
* @returns true if equal
*/
public equalsToFloats(x: number, y: number, z: number, w: number): boolean {
return this.x === x && this.y === y && this.z === z && this.w === w;
}
/**
* Multiplies in place the current Vector4 by the given one.
* @param otherVector vector to multiple with
* @returns the updated Vector4.