import { Vector3 , Quaternion } from "three" ; export const SEAT_ROTATIONS = [ new Quaternion ( ) , new Quaternion ( ) . setFromAxisAngle ( new Vector3 ( 0 , 0 , 1 ) , 1 * ( Math . PI / 2 ) ) , new Quaternion ( ) . setFromAxisAngle ( new Vector3 ( 0 , 0 , 1 ) , 2 * ( Math . PI / 2 ) ) , new Quaternion ( ) . setFromAxisAngle ( new Vector3 ( 0 , 0 , 1 ) , 3 * ( Math . PI / 2 ) ) , ] ; export function shuffle < T > ( arr ) { for ( let i = arr . length - 1 ; i > 0 ; i -- ) { const j = Math . floor ( Math . random ( ) * ( i + 1 ) ) ; const temp = arr [ j ] ; arr [ j ] = arr [ i ] ; arr [ i ] = temp ; } } export function filterMostCommon < T , R > ( arr , func ) { const result = mostCommon ( arr , func ) ; if ( result === null ) { return [ ] ; } return arr . filter ( elem => func ( elem ) === result ) ; } export function mostCommon < T , R > ( arr , func ) { if ( arr . length === 0 ) { return null ; } const counts = new Map ( ) ; for ( const elem of arr ) { const result = func ( elem ) ; const current = counts . get ( result ) ; if ( current !== undefined ) { counts . set ( result , current + 1 ) ; } else { counts . set ( result , 1 ) ; } } const allResults = Array . from ( counts . keys ( ) ) ; allResults . sort ( ( a , b ) => counts . get ( b ) ! - counts . get ( a ) ! ) ; return allResults [ 0 ] ; } export function rectangleOverlap ( x1 , y1 , w1 , h1 , x2 , y2 , w2 , h2 ) { const xa = Math . max ( x1 - w1 / 2 , x2 - w2 / 2 ) ; const xb = Math . min ( x1 + w1 / 2 , x2 + w2 / 2 ) ; const ya = Math . max ( y1 - h1 / 2 , y2 - h2 / 2 ) ; const yb = Math . min ( y1 + h1 / 2 , y2 + h2 / 2 ) ; return Math . max ( 0 , xb - xa ) * Math . max ( 0 , yb - ya ) ; } export class Animation { private startTime = 0 ; private endTime = 1 ; private startPos = 0 ; private endPos = 0 ; private period : number ; pos = - 1 ; constructor ( period ) { this . period = period ; } start ( endPos ) { this . startPos = this . pos ; this . startTime = new Date ( ) . getTime ( ) ; this . endPos = endPos ; this . endTime = this . startTime + this . period * Math . abs ( endPos - this . pos ) ; } update ( ) { if ( this . pos === this . endPos ) { return false ; } const now = new Date ( ) . getTime ( ) ; const delta = ( now - this . startTime ) / ( this . endTime - this . startTime ) ; this . pos = this . startPos + ( this . endPos - this . startPos ) * Math . min ( 1 , delta ) ; return true ; } } export function round3 ( vec , factor ) { vec . x = Math . round ( vec . x * factor ) / factor ; vec . y = Math . round ( vec . y * factor ) / factor ; vec . z = Math . round ( vec . z * factor ) / factor ; } const EPS = 0.05 ; export function rotEquals ( rot1 , rot2 ) { return ( Math . abs ( rot1 . x - rot2 . x ) < EPS && Math . abs ( rot1 . y - rot2 . y ) < EPS && Math . abs ( rot1 . z - rot2 . z ) < EPS && Math . abs ( rot1 . w - rot2 . w ) < EPS ) ; } export function clamp ( val , min , max ) { return Math . min ( max , Math . max ( min , val ) ) ; } export function compareZYX ( a , b ) { if ( a . z !== b . z ) { return a . z - b . z ; } if ( a . y !== b . y ) { return a . y - b . z ; } if ( a . x !== b . x ) { return a . x - b . x ; } return 0 ; }