From eeae90e16fec92f78077fa424c73e86bfc135733 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sat, 11 Mar 2017 10:50:30 -0800 Subject: [PATCH] Quaternion: Removed bi-directionality. --- src/core/Object3D.js | 14 +- src/math/Euler.js | 20 +-- src/math/Quaternion.js | 333 ++++++++++++++--------------------------- 3 files changed, 129 insertions(+), 238 deletions(-) diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 4839dc6a7d..76addf8a60 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -32,24 +32,18 @@ function Object3D() { this.up = Object3D.DefaultUp.clone(); var position = new Vector3(); - var rotation = new Euler(); var quaternion = new Quaternion(); var scale = new Vector3( 1, 1, 1 ); - function onRotationChange() { - - quaternion.setFromEuler( rotation, false ); - - } + var rotation = new Euler(); - function onQuaternionChange() { + function onRotationChange() { - rotation.setFromQuaternion( quaternion, undefined, false ); + quaternion.setFromEuler( rotation ); } rotation.onChange( onRotationChange ); - quaternion.onChange( onQuaternionChange ); Object.defineProperties( this, { position: { @@ -123,7 +117,7 @@ Object.assign( Object3D.prototype, EventDispatcher.prototype, { setRotationFromEuler: function ( euler ) { - this.quaternion.setFromEuler( euler, true ); + this.quaternion.setFromEuler( euler ); }, diff --git a/src/math/Euler.js b/src/math/Euler.js index ae8269abf8..5cc852c902 100644 --- a/src/math/Euler.js +++ b/src/math/Euler.js @@ -1,14 +1,14 @@ -import { Quaternion } from './Quaternion'; -import { Vector3 } from './Vector3'; -import { Matrix4 } from './Matrix4'; -import { _Math } from './Math'; - /** * @author mrdoob / http://mrdoob.com/ * @author WestLangley / http://github.com/WestLangley * @author bhouston / http://clara.io */ +import { Quaternion } from './Quaternion'; +import { Vector3 } from './Vector3'; +import { Matrix4 } from './Matrix4'; +import { _Math } from './Math'; + function Euler( x, y, z, order ) { this._x = x || 0; @@ -24,7 +24,7 @@ Euler.DefaultOrder = 'XYZ'; Object.defineProperties( Euler.prototype, { - "x" : { + x: { get: function () { @@ -41,7 +41,7 @@ Object.defineProperties( Euler.prototype, { }, - "y" : { + y: { get: function () { @@ -58,7 +58,7 @@ Object.defineProperties( Euler.prototype, { }, - "z" : { + z: { get: function () { @@ -75,7 +75,7 @@ Object.defineProperties( Euler.prototype, { }, - "order" : { + order: { get: function () { @@ -92,7 +92,7 @@ Object.defineProperties( Euler.prototype, { } -}); +} ); Object.assign( Euler.prototype, { diff --git a/src/math/Quaternion.js b/src/math/Quaternion.js index 2bb0c3e931..8ad33e4fcf 100644 --- a/src/math/Quaternion.js +++ b/src/math/Quaternion.js @@ -1,5 +1,3 @@ -import { Vector3 } from './Vector3'; - /** * @author mikael emtinger / http://gomo.se/ * @author alteredq / http://alteredqualia.com/ @@ -7,25 +5,26 @@ import { Vector3 } from './Vector3'; * @author bhouston / http://clara.io */ +import { Vector3 } from './Vector3'; + function Quaternion( x, y, z, w ) { - this._x = x || 0; - this._y = y || 0; - this._z = z || 0; - this._w = ( w !== undefined ) ? w : 1; + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = ( w !== undefined ) ? w : 1; } Object.assign( Quaternion, { - slerp: function( qa, qb, qm, t ) { + slerp: function ( qa, qb, qm, t ) { return qm.copy( qa ).slerp( qb, t ); }, - slerpFlat: function( - dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { + slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { // fuzz-free, array-based Quaternion SLERP operation @@ -89,88 +88,14 @@ Object.assign( Quaternion, { } ); -Object.defineProperties( Quaternion.prototype, { - - "x" : { - - get: function () { - - return this._x; - - }, - - set: function ( value ) { - - this._x = value; - this.onChangeCallback(); - - } - - }, - - "y" : { - - get: function () { - - return this._y; - - }, - - set: function ( value ) { - - this._y = value; - this.onChangeCallback(); - - } - - }, - - "z" : { - - get: function () { - - return this._z; - - }, - - set: function ( value ) { - - this._z = value; - this.onChangeCallback(); - - } - - }, - - "w" : { - - get: function () { - - return this._w; - - }, - - set: function ( value ) { - - this._w = value; - this.onChangeCallback(); - - } - - } - -}); - Object.assign( Quaternion.prototype, { set: function ( x, y, z, w ) { - this._x = x; - this._y = y; - this._z = z; - this._w = w; - - this.onChangeCallback(); + this.x = x; + this.y = y; + this.z = z; + this.w = w; return this; @@ -178,24 +103,22 @@ Object.assign( Quaternion.prototype, { clone: function () { - return new this.constructor( this._x, this._y, this._z, this._w ); + return new this.constructor( this.x, this.y, this.z, this.w ); }, copy: function ( quaternion ) { - this._x = quaternion.x; - this._y = quaternion.y; - this._z = quaternion.z; - this._w = quaternion.w; - - this.onChangeCallback(); + this.x = quaternion.x; + this.y = quaternion.y; + this.z = quaternion.z; + this.w = quaternion.w; return this; }, - setFromEuler: function ( euler, update ) { + setFromEuler: function ( euler ) { if ( ( euler && euler.isEuler ) === false ) { @@ -203,7 +126,7 @@ Object.assign( Quaternion.prototype, { } - var x = euler._x, y = euler._y, z = euler._z, order = euler.order; + var x = euler.x, y = euler.y, z = euler.z, order = euler.order; // http://www.mathworks.com/matlabcentral/fileexchange/ // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ @@ -222,50 +145,48 @@ Object.assign( Quaternion.prototype, { if ( order === 'XYZ' ) { - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; } else if ( order === 'YXZ' ) { - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; } else if ( order === 'ZXY' ) { - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + this.x = s1 * c2 * c3 - c1 * s2 * s3; + this.y = c1 * s2 * c3 + s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; } else if ( order === 'ZYX' ) { - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + this.x = s1 * c2 * c3 - c1 * s2 * s3; + this.y = c1 * s2 * c3 + s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; } else if ( order === 'YZX' ) { - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 + s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; } else if ( order === 'XZY' ) { - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + this.x = s1 * c2 * c3 - c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; } - if ( update !== false ) this.onChangeCallback(); - return this; }, @@ -278,12 +199,10 @@ Object.assign( Quaternion.prototype, { var halfAngle = angle / 2, s = Math.sin( halfAngle ); - this._x = axis.x * s; - this._y = axis.y * s; - this._z = axis.z * s; - this._w = Math.cos( halfAngle ); - - this.onChangeCallback(); + this.x = axis.x * s; + this.y = axis.y * s; + this.z = axis.z * s; + this.w = Math.cos( halfAngle ); return this; @@ -308,42 +227,40 @@ Object.assign( Quaternion.prototype, { s = 0.5 / Math.sqrt( trace + 1.0 ); - this._w = 0.25 / s; - this._x = ( m32 - m23 ) * s; - this._y = ( m13 - m31 ) * s; - this._z = ( m21 - m12 ) * s; + this.w = 0.25 / s; + this.x = ( m32 - m23 ) * s; + this.y = ( m13 - m31 ) * s; + this.z = ( m21 - m12 ) * s; } else if ( m11 > m22 && m11 > m33 ) { s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); - this._w = ( m32 - m23 ) / s; - this._x = 0.25 * s; - this._y = ( m12 + m21 ) / s; - this._z = ( m13 + m31 ) / s; + this.w = ( m32 - m23 ) / s; + this.x = 0.25 * s; + this.y = ( m12 + m21 ) / s; + this.z = ( m13 + m31 ) / s; } else if ( m22 > m33 ) { s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); - this._w = ( m13 - m31 ) / s; - this._x = ( m12 + m21 ) / s; - this._y = 0.25 * s; - this._z = ( m23 + m32 ) / s; + this.w = ( m13 - m31 ) / s; + this.x = ( m12 + m21 ) / s; + this.y = 0.25 * s; + this.z = ( m23 + m32 ) / s; } else { s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); - this._w = ( m21 - m12 ) / s; - this._x = ( m13 + m31 ) / s; - this._y = ( m23 + m32 ) / s; - this._z = 0.25 * s; + this.w = ( m21 - m12 ) / s; + this.x = ( m13 + m31 ) / s; + this.y = ( m23 + m32 ) / s; + this.z = 0.25 * s; } - this.onChangeCallback(); - return this; }, @@ -385,10 +302,10 @@ Object.assign( Quaternion.prototype, { } - this._x = v1.x; - this._y = v1.y; - this._z = v1.z; - this._w = r; + this.x = v1.x; + this.y = v1.y; + this.z = v1.z; + this.w = r; return this.normalize(); @@ -404,11 +321,9 @@ Object.assign( Quaternion.prototype, { conjugate: function () { - this._x *= - 1; - this._y *= - 1; - this._z *= - 1; - - this.onChangeCallback(); + this.x *= - 1; + this.y *= - 1; + this.z *= - 1; return this; @@ -416,19 +331,19 @@ Object.assign( Quaternion.prototype, { dot: function ( v ) { - return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; + return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; }, lengthSq: function () { - return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; + return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; }, length: function () { - return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w ); + return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); }, @@ -438,24 +353,22 @@ Object.assign( Quaternion.prototype, { if ( l === 0 ) { - this._x = 0; - this._y = 0; - this._z = 0; - this._w = 1; + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 1; } else { l = 1 / l; - this._x = this._x * l; - this._y = this._y * l; - this._z = this._z * l; - this._w = this._w * l; + this.x = this.x * l; + this.y = this.y * l; + this.z = this.z * l; + this.w = this.w * l; } - this.onChangeCallback(); - return this; }, @@ -483,15 +396,13 @@ Object.assign( Quaternion.prototype, { // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm - var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; - var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; + var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w; + var qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w; - this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; - this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; - this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; - this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; - - this.onChangeCallback(); + this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; + this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; + this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; + this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; return this; @@ -502,18 +413,18 @@ Object.assign( Quaternion.prototype, { if ( t === 0 ) return this; if ( t === 1 ) return this.copy( qb ); - var x = this._x, y = this._y, z = this._z, w = this._w; + var x = this.x, y = this.y, z = this.z, w = this.w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ - var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; + var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z; if ( cosHalfTheta < 0 ) { - this._w = - qb._w; - this._x = - qb._x; - this._y = - qb._y; - this._z = - qb._z; + this.w = - qb.w; + this.x = - qb.x; + this.y = - qb.y; + this.z = - qb.z; cosHalfTheta = - cosHalfTheta; @@ -525,10 +436,10 @@ Object.assign( Quaternion.prototype, { if ( cosHalfTheta >= 1.0 ) { - this._w = w; - this._x = x; - this._y = y; - this._z = z; + this.w = w; + this.x = x; + this.y = y; + this.z = z; return this; @@ -538,10 +449,10 @@ Object.assign( Quaternion.prototype, { if ( Math.abs( sinHalfTheta ) < 0.001 ) { - this._w = 0.5 * ( w + this._w ); - this._x = 0.5 * ( x + this._x ); - this._y = 0.5 * ( y + this._y ); - this._z = 0.5 * ( z + this._z ); + this.w = 0.5 * ( w + this.w ); + this.x = 0.5 * ( x + this.x ); + this.y = 0.5 * ( y + this.y ); + this.z = 0.5 * ( z + this.z ); return this; @@ -551,12 +462,10 @@ Object.assign( Quaternion.prototype, { var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; - this._w = ( w * ratioA + this._w * ratioB ); - this._x = ( x * ratioA + this._x * ratioB ); - this._y = ( y * ratioA + this._y * ratioB ); - this._z = ( z * ratioA + this._z * ratioB ); - - this.onChangeCallback(); + this.w = ( w * ratioA + this.w * ratioB ); + this.x = ( x * ratioA + this.x * ratioB ); + this.y = ( y * ratioA + this.y * ratioB ); + this.z = ( z * ratioA + this.z * ratioB ); return this; @@ -564,7 +473,7 @@ Object.assign( Quaternion.prototype, { equals: function ( quaternion ) { - return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); + return ( quaternion.x === this.x ) && ( quaternion.y === this.y ) && ( quaternion.z === this.z ) && ( quaternion.w === this.w ); }, @@ -572,12 +481,10 @@ Object.assign( Quaternion.prototype, { if ( offset === undefined ) offset = 0; - this._x = array[ offset ]; - this._y = array[ offset + 1 ]; - this._z = array[ offset + 2 ]; - this._w = array[ offset + 3 ]; - - this.onChangeCallback(); + this.x = array[ offset ]; + this.y = array[ offset + 1 ]; + this.z = array[ offset + 2 ]; + this.w = array[ offset + 3 ]; return this; @@ -588,24 +495,14 @@ Object.assign( Quaternion.prototype, { if ( array === undefined ) array = []; if ( offset === undefined ) offset = 0; - array[ offset ] = this._x; - array[ offset + 1 ] = this._y; - array[ offset + 2 ] = this._z; - array[ offset + 3 ] = this._w; + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; + array[ offset + 3 ] = this.w; return array; - }, - - onChange: function ( callback ) { - - this.onChangeCallback = callback; - - return this; - - }, - - onChangeCallback: function () {} + } } ); -- GitLab