Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rotation from one vector3 to another #13004

Merged
merged 7 commits into from
Sep 26, 2022
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 98 additions & 10 deletions packages/dev/core/src/Maths/math.vector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ export class Vector2 {
/**
* 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
* @returns the result
*/
public negateToRef(result: Vector2): Vector2 {
return result.copyFromFloats(this.x * -1, this.y * -1);
Expand Down Expand Up @@ -983,7 +983,7 @@ export class Vector3 {
* Example Playground https://playground.babylonjs.com/#R1F8YU#6
* @param otherVector defines the second operand
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
* @returns the result
*/
public addToRef(otherVector: DeepImmutable<Vector3>, result: Vector3): Vector3 {
return result.copyFromFloats(this._x + otherVector._x, this._y + otherVector._y, this._z + otherVector._z);
Expand Down Expand Up @@ -1017,7 +1017,7 @@ export class Vector3 {
* Example Playground https://playground.babylonjs.com/#R1F8YU#63
* @param otherVector defines the second operand
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
* @returns the result
*/
public subtractToRef(otherVector: DeepImmutable<Vector3>, result: Vector3): Vector3 {
return this.subtractFromFloatsToRef(otherVector._x, otherVector._y, otherVector._z, result);
Expand All @@ -1042,7 +1042,7 @@ export class Vector3 {
* @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
* @returns the result
*/
public subtractFromFloatsToRef(x: number, y: number, z: number, result: Vector3): Vector3 {
return result.copyFromFloats(this._x - x, this._y - y, this._z - z);
Expand Down Expand Up @@ -1073,7 +1073,7 @@ export class Vector3 {
* Negate the current Vector3 and stores the result in the given vector "result" coordinates
* Example Playground https://playground.babylonjs.com/#R1F8YU#37
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
* @returns the result
*/
public negateToRef(result: Vector3): Vector3 {
return result.copyFromFloats(this._x * -1, this._y * -1, this._z * -1);
Expand Down Expand Up @@ -1107,18 +1107,54 @@ export class Vector3 {
* Example Playground https://playground.babylonjs.com/#R1F8YU#57
* @param scale defines the multiplier factor
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
* @returns the result
*/
public scaleToRef(scale: number, result: Vector3): Vector3 {
return result.copyFromFloats(this._x * scale, this._y * scale, this._z * scale);
}

/**
* Creates a vector normal (perpendicular) to the current Vector3
* returns the vector normal
*/
public getNormal(): Vector3 {
const ref: Vector3 = MathTmp.Vector3[0];
return this.getNormalToRef(ref);
}

/**
* Creates a vector normal (perpendicular) to the current Vector3 and stores the result in the given vector
* @param result defines the Vector3 object where to store the resultant normal
* returns the result
*/
public getNormalToRef(result: DeepImmutable<Vector3>): Vector3 {
sebavan marked this conversation as resolved.
Show resolved Hide resolved
/**
* Calculates the spherical coordinates of the current vector
* so saves on memory rather than importing whole Spherical Class
*/
const radius: number = this.length();
let theta: number = Math.acos(this.y / radius);
const phi = Math.atan2(this.z, this.x);
//makes angle 90 degs to current vector
if (theta > Math.PI / 2) {
theta -= Math.PI / 2;
} else {
theta += Math.PI / 2;
}
//Calculates resutant normal vector from spherical coordinate of perpendicular vector
const x = radius * Math.sin(theta) * Math.cos(phi);
const y = radius * Math.cos(theta);
const z = radius * Math.sin(theta) * Math.sin(phi);
result.set(x, y, z);
return result;
}

/**
* Rotates the vector using the given unit quaternion and stores the new vector in result
* Example Playground https://playground.babylonjs.com/#R1F8YU#9
* @param q the unit quaternion representing the rotation
* @param result the output vector
* @returns the current Vector3
* @returns the result
*/
public applyRotationQuaternionToRef(q: Quaternion, result: Vector3): Vector3 {
const ix = q.w * this.x + q.y * this.z - q.z * this.y;
Expand Down Expand Up @@ -1277,7 +1313,7 @@ export class Vector3 {
* Example Playground https://playground.babylonjs.com/#R1F8YU#33
* @param otherVector defines the second operand
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
* @returns the result
*/
public multiplyToRef(otherVector: DeepImmutable<Vector3>, result: Vector3): Vector3 {
return result.copyFromFloats(this._x * otherVector._x, this._y * otherVector._y, this._z * otherVector._z);
Expand Down Expand Up @@ -1310,7 +1346,7 @@ export class Vector3 {
* Example Playground https://playground.babylonjs.com/#R1F8YU#18
* @param otherVector defines the second operand
* @param result defines the Vector3 object where to store the result
* @returns the current Vector3
* @returns the result
*/
public divideToRef(otherVector: DeepImmutable<Vector3>, result: Vector3): Vector3 {
return result.copyFromFloats(this._x / otherVector._x, this._y / otherVector._y, this._z / otherVector._z);
Expand Down Expand Up @@ -1661,6 +1697,30 @@ export class Vector3 {
return s;
}

/**
* Get rotation needed to to rotate from one Vector3 onto another Vector3
* @param fromVector the starting vector
* @param toVector the ending vector
* @returns the rotation needed
*/
public static RotationFromOnto(fromVector: DeepImmutable<Vector3>, toVector: DeepImmutable<Vector3>) {
sebavan marked this conversation as resolved.
Show resolved Hide resolved
const ref: Quaternion = Quaternion.Zero();
return Quaternion.RotationQuaternionFromOntoToRef(fromVector, toVector, ref).toEulerAngles();
}

/**
* Get rotation needed to to rotate from one Vector3 onto another Vector3 and store in a result Vector3
* @param fromVector the starting vector
* @param toVector the ending vector
* @param result the rotation needed
* @returns the result
*/
public static RotationFromOntoToRef(fromVector: DeepImmutable<Vector3>, toVector: DeepImmutable<Vector3>, result: DeepImmutable<Vector3>) {
const ref: Quaternion = Quaternion.Zero();
result = Quaternion.RotationQuaternionFromOntoToRef(fromVector, toVector, ref).toEulerAngles();
return result;
}

/**
* Get angle between two vectors
* Example Playground https://playground.babylonjs.com/#R1F8YU#86
Expand Down Expand Up @@ -2963,7 +3023,7 @@ export class Vector4 {
/**
* 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
* @returns the result
*/
public negateToRef(result: Vector4): Vector4 {
return result.copyFromFloats(this.x * -1, this.y * -1, this.z * -1, this.w * -1);
Expand Down Expand Up @@ -4113,6 +4173,34 @@ export class Quaternion {
}
}

/**
* Creates the rotation quaternion needed to rotate from one Vector3 onto another Vector3
* @param fromVector the starting vector
* @param toVector the ending vector
* @returns the rotation quaternion needed
*/
public static RotationQuaternionFromOnto(fromVector: DeepImmutable<Vector3>, toVector: DeepImmutable<Vector3>) {
const ref: Quaternion = Quaternion.Zero();
return Quaternion.RotationQuaternionFromOntoToRef(fromVector, toVector, ref);
}

/**
* Creates the rotation quaternion needed to rotate from one Vector3 onto another Vector3 and stores in a result Quaternion
* @param fromVector the starting vector
* @param toVector the ending vector
* @param result the rotation quaternion needed
* @returns the result
*/
public static RotationQuaternionFromOntoToRef(fromVector: DeepImmutable<Vector3>, toVector: DeepImmutable<Vector3>, result: Quaternion) {
const normal: Vector3 = Vector3.Cross(fromVector, toVector);
if (normal.equals(Vector3.Zero())) {
RaananW marked this conversation as resolved.
Show resolved Hide resolved
fromVector.getNormalToRef(normal);
}
const angle = Vector3.GetAngleBetweenVectors(fromVector, toVector, normal);
result = Quaternion.RotationAxis(normal, angle);
RaananW marked this conversation as resolved.
Show resolved Hide resolved
return result;
}

/**
* Returns the dot product (float) between the quaternions "left" and "right"
* @param left defines the left operand
Expand Down