diff --git a/docs/api/math/Quaternion.html b/docs/api/math/Quaternion.html
index a9c4b114e0f7b096fae86e3a8aeb45fc7e59fe44..9c466ec348d2c0c0b138ce3cd18855c7fec73ed7 100644
--- a/docs/api/math/Quaternion.html
+++ b/docs/api/math/Quaternion.html
@@ -169,6 +169,15 @@
[method:Quaternion premultiply]( [param:Quaternion q] )
Pre-multiplies this quaternion by [page:Quaternion q].
+ [method:Quaternion transformTo]( [param:Quaternion q], [param:Float step] )
+
+ [page:Quaternion q] - The target quaternion.
+ [page:float step] - The angular step in radians.
+
+ Transforms this quaternion by a given angular step to the defined quaternion *q*.
+ The method ensures that the final quaternion will not overshoot *q*.
+
+
[method:Quaternion slerp]( [param:Quaternion qb], [param:float t] )
[page:Quaternion qb] - The other quaternion rotation
diff --git a/examples/files.js b/examples/files.js
index 32adbd226fad8696c9e71b01a464415ee198807a..7e46ac0a49936027318c81479eb3521a3ef256d0 100644
--- a/examples/files.js
+++ b/examples/files.js
@@ -183,6 +183,7 @@ var files = {
"webgl_materials_video",
"webgl_materials_video_webcam",
"webgl_materials_wireframe",
+ "webgl_math_orientation_transform",
"webgl_mirror",
"webgl_mirror_nodes",
"webgl_modifier_simplifier",
diff --git a/examples/webgl_math_orientation_transform.html b/examples/webgl_math_orientation_transform.html
new file mode 100644
index 0000000000000000000000000000000000000000..f23cc4e21168e3c25ae2d861df66729c997e308d
--- /dev/null
+++ b/examples/webgl_math_orientation_transform.html
@@ -0,0 +1,156 @@
+
+
+
+ three.js transform orientation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
three.js - gradually transform an orientation to a target orientation
+
+
+
+
+
+
diff --git a/src/math/Quaternion.js b/src/math/Quaternion.js
index b7b6458b5101c68570804fc2036a4a8232924bd6..0eff6b4c3ee4a9a19ee667e1ac4d72680734b7e8 100644
--- a/src/math/Quaternion.js
+++ b/src/math/Quaternion.js
@@ -400,6 +400,20 @@ Object.assign( Quaternion.prototype, {
},
+ transformTo: function ( q, step ) {
+
+ var angle = this.angleTo( q );
+
+ if ( angle === 0 ) return this;
+
+ var t = Math.min( 1, step / angle );
+
+ this.slerp( q, t );
+
+ return this;
+
+ },
+
inverse: function () {
// quaternion is assumed to have unit length
diff --git a/test/unit/src/math/Quaternion.tests.js b/test/unit/src/math/Quaternion.tests.js
index b00c3d64f26f6ab26984a1338889c2b347f0ee97..698b1e5179f7565cf380a5e7edabead2d80a6dd4 100644
--- a/test/unit/src/math/Quaternion.tests.js
+++ b/test/unit/src/math/Quaternion.tests.js
@@ -403,6 +403,26 @@ export default QUnit.module( 'Maths', () => {
} );
+ QUnit.test( "transformTo", ( assert ) => {
+
+ var a = new Quaternion();
+ var b = new Quaternion().setFromEuler( new Euler( 0, Math.PI, 0 ) );
+ var c = new Quaternion();
+
+ var halfPI = Math.PI * 0.5;
+
+ a.transformTo( b, 0 );
+ assert.ok( a.equals( a ) === true, "Passed!" );
+
+ a.transformTo( b, Math.PI * 2 ); // test overshoot
+ assert.ok( a.equals( b ) === true, "Passed!" );
+
+ a.set( 0, 0, 0, 1 );
+ a.transformTo( b, halfPI );
+ assert.ok( a.angleTo( c ) - halfPI <= eps, "Passed!" );
+
+ } );
+
QUnit.test( "inverse/conjugate", ( assert ) => {
var a = new Quaternion( x, y, z, w );