Skip to content

Commit

Permalink
Merge pull request #13004 from BabylonJSGuide/master
Browse files Browse the repository at this point in the history
Add rotation from one vector3 to another
  • Loading branch information
sebavan authored Sep 26, 2022
2 parents 0fa67c9 + a2a2a03 commit c67d38e
Showing 1 changed file with 66 additions and 10 deletions.
76 changes: 66 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,46 @@ 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 and stores the result in the given vector
* @param result defines the Vector3 object where to store the resultant normal
* returns the result
* @hidden
*/
public _getNormalToRef(result: DeepImmutable<Vector3>): Vector3 {
/**
* 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 +1305,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 +1338,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 @@ -2960,7 +2988,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 @@ -4110,6 +4138,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: DeepImmutable<Quaternion>) {
const normal: Vector3 = TmpVectors.Vector3[0];
Vector3.CrossToRef(fromVector, toVector, normal);
if (normal.equals(Vector3.ZeroReadOnly)) {
fromVector._getNormalToRef(normal);
}
const angle = Vector3.GetAngleBetweenVectors(fromVector, toVector, normal);
return Quaternion.RotationAxisToRef(normal, angle, result);
}

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

0 comments on commit c67d38e

Please sign in to comment.