1- import { Euler , Matrix4 , Plane , Quaternion , Vector3 , Vector3Tuple } from 'three'
1+ import { Euler , EulerOrder , Matrix4 , Plane , Quaternion , Vector3 , Vector3Tuple } from 'three'
22import { Axis , HandleTransformState } from '../state.js'
33import { HandleOptions , HandleTransformOptions } from '../store.js'
44import { clamp } from 'three/src/math/MathUtils.js'
@@ -13,6 +13,12 @@ export type BaseHandleStoreData = {
1313 initialTargetScale : Vector3
1414}
1515
16+ const axisFirstOrder = {
17+ x : 'XYZ' ,
18+ y : 'YXZ' ,
19+ z : 'ZXY' ,
20+ }
21+
1622export function computeHandleTransformState (
1723 time : number ,
1824 pointerAmount : number ,
@@ -47,6 +53,7 @@ export function computeHandleTransformState(
4753 quaternion . copy ( storeData . initialTargetQuaternion )
4854 rotation = storeData . initialTargetRotation . clone ( )
4955 } else if (
56+ Array . isArray ( rotateOptions ) ||
5057 rotateOptions === true ||
5158 ( typeof rotateOptions != 'string' &&
5259 ! Array . isArray ( rotateOptions ) &&
@@ -55,6 +62,18 @@ export function computeHandleTransformState(
5562 rotateOptions . z === true )
5663 ) {
5764 rotation = new Euler ( ) . setFromQuaternion ( quaternion , storeData . initialTargetRotation . order )
65+ } else if ( typeof rotateOptions === 'string' ) {
66+ const order = axisFirstOrder [ rotateOptions ]
67+ rotation = new Euler ( ) . setFromQuaternion ( quaternion )
68+ for ( const orderElement of order ) {
69+ const axis = orderElement . toLowerCase ( ) as Axis
70+ if ( axis === rotateOptions ) {
71+ continue
72+ }
73+ rotation [ axis ] = 0
74+ }
75+ rotation . order = storeData . initialTargetRotation . order
76+ quaternion . setFromEuler ( rotation )
5877 } else {
5978 rotation = applyTransformOptionsToRotation ( quaternion , storeData . initialTargetRotation , rotateOptions )
6079 }
@@ -105,39 +124,28 @@ function getPerpendicular(target: Vector3, from: Vector3): void {
105124 target . set ( - from . y , from . x , 0 )
106125}
107126
108- const quaternionHelper = new Quaternion ( )
109- const eulerHelper = new Euler ( )
110-
111127export function applyTransformOptionsToRotation (
112128 currentRotation : Quaternion ,
113129 initialRotation : Euler ,
114- options : HandleTransformOptions ,
130+ options : Exclude < HandleTransformOptions , boolean | Array < Vector3Tuple > | Axis > ,
115131) : Euler {
116- const result = new Euler ( 0 , 0 , 0 , initialRotation . order )
117- let inverted = false
118- for ( const axisElement of initialRotation . order ) {
119- const axis = axisElement . toLowerCase ( ) as Axis
120- const axisAngle =
121- eulerHelper . setFromQuaternion ( currentRotation , initialRotation . order ) [ axis ] + ( inverted ? Math . PI : 0 )
122- const transformedAxisAngle = Array . isArray ( options )
123- ? axisAngle
124- : applyTransformOptionsToAxis ( axis , axisAngle , initialRotation [ axis ] , options )
125-
126- if ( Math . abs ( axisAngle - transformedAxisAngle ) > Math . PI / 2 ) {
127- inverted = ! inverted
128- }
129-
130- if ( axisAngle != transformedAxisAngle ) {
131- //currentRotation = currentRotation * result-1 * delta * result
132- currentRotation . multiply ( quaternionHelper . setFromEuler ( result ) . invert ( ) )
133- const delta = axisAngle - transformedAxisAngle
134- result [ axis ] = delta
135- currentRotation . multiply ( quaternionHelper . setFromEuler ( result ) )
132+ let orderEnabledAxis = ''
133+ let orderDisabledAxis = ''
134+ for ( const orderElement of initialRotation . order ) {
135+ if ( options [ orderElement . toLowerCase ( ) as Axis ] === false ) {
136+ orderDisabledAxis += orderElement
137+ } else {
138+ orderEnabledAxis += orderElement
136139 }
137-
138- result [ axis ] = transformedAxisAngle
140+ }
141+ const order = ( orderEnabledAxis + orderDisabledAxis ) as EulerOrder
142+ const result = new Euler ( ) . setFromQuaternion ( currentRotation , order )
143+ for ( const orderElement of order ) {
144+ const axis = orderElement . toLowerCase ( ) as Axis
145+ result [ axis ] = applyTransformOptionsToAxis ( axis , result [ axis ] , initialRotation [ axis ] , options )
139146 }
140147 currentRotation . setFromEuler ( result )
148+ result . setFromQuaternion ( currentRotation , initialRotation . order )
141149 return result
142150}
143151
@@ -453,7 +461,6 @@ export function projectOntoAxis(
453461 //angleDifference is between 3° and 6°
454462 //factor = 1 means that we want 100% from worldPoint and 0 from project point
455463 const factor = ( angleDifference - _3Degree ) / _3Degree
456- console . log ( factor )
457464 projectPointOntoAxis ( vectorHelper , initialWorldPoint , axis )
458465 worldPoint . multiplyScalar ( factor ) . addScaledVector ( vectorHelper , 1 - factor )
459466 }
0 commit comments