22/* eslint no-param-reassign: 0 */
33/* eslint getter-return: 0 */
44/* eslint new-cap: 0 */
5+ /* eslint no-prototype-builtins: 0 */
56
67const X = 0 ;
78const Y = 1 ;
89const Z = 2 ;
910const DEFAULT = 3 ;
11+ const VECTOR_LENGTH = Symbol ( 'vector length' ) ;
1012
1113let inProgress = DEFAULT ;
1214let inVector ;
@@ -21,10 +23,21 @@ function handleProgess(progess, alg, resVec) {
2123 return alg ( resVec ) ;
2224}
2325
26+ function getVectorLength ( vec ) {
27+ return vec [ VECTOR_LENGTH ] !== 2 ? 3 : 2 ;
28+ }
29+
30+ function maxVector ( v1 , v2 ) {
31+ if ( getVectorLength ( v1 ) > getVectorLength ( v2 ) ) {
32+ return v1 ;
33+ }
34+ return v2 ;
35+ }
36+
2437/**
2538 * @param {() => number } alg
26- * @param {{ x: number, y: number, z: number }= } result
27- * @return {{ x: number, y: number, z: number } | number }
39+ * @param {{ x: number, y: number, z: number } | { x: number, y: number } = } result
40+ * @return {{ x: number, y: number, z: number } | { x: number, y: number } | number }
2841 */
2942export function operatorCalc ( alg , result ) {
3043 if ( typeof alg !== 'function' ) {
@@ -43,19 +56,39 @@ export function operatorCalc(alg, result) {
4356 return x ;
4457 }
4558
59+ let calcZ = false ;
60+ if ( inVector ) {
61+ calcZ = getVectorLength ( inVector ) !== 2 ;
62+ } else {
63+ calcZ = result . length !== 2 ;
64+ }
65+
4666 const y = handleProgess ( Y , alg , resVec ) ;
47- const z = handleProgess ( Z , alg , resVec ) ;
4867
49- if ( noRes ) {
50- return new inVector . constructor ( x , y , z ) ;
51- }
52- if ( funRes ) {
53- return result ( x , y , z ) ;
54- }
68+ if ( ! calcZ ) {
69+ if ( noRes ) {
70+ return new inVector . constructor ( x , y ) ;
71+ }
72+ if ( funRes ) {
73+ return result ( x , y ) ;
74+ }
5575
56- result . x = x ;
57- result . y = y ;
58- result . z = z ;
76+ result . x = x ;
77+ result . y = y ;
78+ } else {
79+ const z = handleProgess ( Z , alg , resVec ) ;
80+
81+ if ( noRes ) {
82+ return new inVector . constructor ( x , y , z ) ;
83+ }
84+ if ( funRes ) {
85+ return result ( x , y , z ) ;
86+ }
87+
88+ result . x = x ;
89+ result . y = y ;
90+ result . z = z ;
91+ }
5992 return result ;
6093 } finally {
6194 inProgress = DEFAULT ;
@@ -70,14 +103,17 @@ export function cachedValueOf(VectorClass) {
70103
71104 Vector [ name ] = function ( ) {
72105 if ( inProgress === X ) {
73- inVector = this ;
106+ inVector = inVector ? maxVector ( inVector , this ) : this ;
74107 return this . x ;
75108 }
76109 if ( inProgress === Y ) {
77110 return this . y ;
78111 }
79112 if ( inProgress === Z ) {
80- return this . z ;
113+ if ( this [ VECTOR_LENGTH ] !== 2 ) {
114+ return this . z ;
115+ }
116+ return 0 ;
81117 }
82118 return org . call ( this ) ;
83119 } ;
@@ -129,3 +165,9 @@ export function cachedGetter(VectorClass, name) {
129165 get : bindCache ( org )
130166 } ) ;
131167}
168+
169+ export function defineVectorLength ( VectorClass , value ) {
170+ const Vector = VectorClass . prototype ;
171+
172+ Object . defineProperty ( Vector , VECTOR_LENGTH , { value } ) ;
173+ }
0 commit comments