/* Ċ Ġ* ĠCopyright Ġ 2 0 1 8 ĠGoogle ĠLLC ĠAll ĠRights ĠReserved . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġcom . google . ar . scene form . ux Ċ Ċ import Ġcom . google . ar . core . Hit Result Ċ import Ġcom . google . ar . core . Plane Ċ import Ġcom . google . ar . core . Tracking State Ċ import Ġcom . google . ar . scene form . Anchor Node Ċ import Ġcom . google . ar . scene form . Ar Scene View Ċ import Ġcom . google . ar . scene form . Frame Time Ċ import Ġcom . google . ar . scene form . Node Ċ import Ġcom . google . ar . scene form . math . Math Helper Ċ import Ġcom . google . ar . scene form . math . Quaternion Ċ import Ġcom . google . ar . scene form . math . Vector 3 Ċ import Ġcom . google . ar . scene form . utilities . Preconditions Ċ import Ġjava . util .* Ċ Ċ /** Ċ Ġ* ĠMan ip ulates Ġthe Ġposition Ġof Ġa Ġ[ Base Transform able Node ] Ġusing Ġa Ġ[ Ġ]. ĠIf Ġnot Ġselected , Ġthe Ġ[ Base Transform able Node ] Ġwill Ġbecome Ġselected Ċ Ġ* Ġwhen Ġthe Ġ[ Drag Gesture ] Ġstarts . Ċ Ġ*/ Ċ class ĠTranslation Controller ( ĊĠĠĠ Ġtransform able Node : ĠBase Transform able Node , ĊĠĠĠ Ġgesture Recognizer : ĠDrag Gesture Recognizer , Ċ ) Ġ: ĠBase Transformation Controller < Drag Gesture >( transform able Node , Ġgesture Recognizer ) Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġlast Ar Hit Result : ĠHit Result ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġdesired Local Position : ĠVector 3 ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġdesired Local Rotation : ĠQuaternion ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġval Ġinitial Forward In Local Ġ= ĠVector 3 () ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGets Ġa Ġreference Ġto Ġthe ĠEnum Set Ġthat Ġdetermines Ġwhich Ġtypes Ġof ĠAr Core ĠPlan es Ġthis ĊĠĠĠĠ Ġ* ĠTranslation Controller Ġis Ġallowed Ġto Ġtranslate Ġon . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĠSets Ġwhich Ġtypes Ġof ĠAr Core ĠPlan es Ġthis ĠTranslation Controller Ġis Ġallowed Ġto Ġtranslate Ġon . Ġ Ġ*/ ĊĠĠĠ Ġvar Ġallowed Plane Types Ġ= ĠEnum Set . all Of ( Plane . Type :: class . java ) ĊĊĠĠĠ Ġoverride Ġfun Ġon Updated ( node : ĠNode , Ġframe Time : ĠFrame Time ) Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate Position ( frame Time ) ĊĠĠĠĠĠĠĠ Ġupdate Rotation ( frame Time ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġis Transform ing : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġsuper . is Transform ing Ġ|| Ġdesired Local Rotation Ġ!= Ġnull Ġ|| Ġdesired Local Position Ġ!= Ġnull ĊĊĠĠĠ Ġoverride Ġfun Ġcan Start Transformation ( gesture : ĠDrag Gesture ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtarget Node Ġ= Ġgesture . target Node Ġ?: Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġval Ġtransform able Node Ġ= Ġtransform able Node ĊĠĠĠĠĠĠĠ Ġif Ġ( target Node Ġ!== Ġtransform able Node Ġ&& Ġ! target Node . is Desc endant Of ( transform able Node )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ(! transform able Node . isSelected () Ġ&& Ġ! transform able Node . select ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġinitial Forward In World Ġ= Ġtransform able Node . forward ĊĠĠĠĠĠĠĠ Ġval Ġparent Ġ= Ġtransform able Node . parent ĊĠĠĠĠĠĠĠ Ġif Ġ( parent Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Forward In Local . set ( parent . world ToLocal Direction ( initial Forward In World )) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Forward In Local . set ( initial Forward In World ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Continue Transformation ( gesture : ĠDrag Gesture ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġscene Ġ= Ġtransform able Node . scene Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġframe Ġ= Ġ( scene . view Ġas ĠAr Scene View ). ar Frame Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġar Camera Ġ= Ġframe . camera ĊĠĠĠĠĠĠĠ Ġif Ġ( ar Camera . tracking State Ġ!= ĠTracking State . TRACK ING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġposition Ġ= Ġgesture . getPosition () ĊĠĠĠĠĠĠĠ Ġval Ġhit Result List Ġ= Ġframe . hit Test ( position . x , Ġposition . y ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġhit Result List . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhit Ġ= Ġhit Result List [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtrack able Ġ= Ġhit . track able ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpose Ġ= Ġhit . hit Pose ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( track able Ġis ĠPlane ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġplane Ġ= Ġtrack able ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( plane . is Pose In Polygon ( pose ) Ġ&& Ġallowed Plane Types . contains ( plane . type )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdesired Local Position Ġ= ĠVector 3 ( pose . tx (), Ġpose . ty (), Ġpose . tz ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdesired Local Rotation Ġ= ĠQuaternion ( pose . qx (), Ġpose . qy (), Ġpose . qz (), Ġpose . qw ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparent Ġ= Ġtransform able Node . parent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( parent Ġ!= Ġnull Ġ&& Ġdesired Local Position Ġ!= Ġnull Ġ&& Ġdesired Local Rotation Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdesired Local Position Ġ= Ġparent . world ToLocal Point ( desired Local Position ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdesired Local Rotation Ġ= ĠQuaternion . multiply ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparent . world Rotation . inverted (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPreconditions . checkNotNull ( desired Local Rotation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdesired Local Rotation Ġ= Ġcalculate Final Desired Local Rotation ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPreconditions . checkNotNull ( desired Local Rotation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Ar Hit Result Ġ= Ġhit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon End Transformation ( gesture : ĠDrag Gesture ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġhit Result Ġ= Ġlast Ar Hit Result Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġif Ġ( hit Result . track able . tracking State Ġ== ĠTracking State . TRACK ING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġanchor Node Ġ= Ġanchor Node Or Die ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġold Anchor Ġ= Ġanchor Node . anchor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġold Anchor ?. detach () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Anchor Ġ= Ġhit Result . create Anchor () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġworld Position Ġ= Ġtransform able Node . world Position ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġworld Rotation Ġ= Ġtransform able Node . world Rotation ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġfinal Desired World Rotation Ġ= Ġworld Rotation ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSince Ġwe Ġchange Ġthe Ġanchor , Ġwe Ġneed Ġto Ġupdate Ġthe Ġinitial Forward In Local Ġinto Ġthe Ġnew ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcoordinate Ġspace . ĠLocal Ġvariable Ġfor Ġnull ness Ġanalysis . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdesired Local Rotation Ġ= Ġdesired Local Rotation ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( desired Local Rotation Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransform able Node . local Rotation Ġ= Ġdesired Local Rotation ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfinal Desired World Rotation Ġ= Ġtransform able Node . world Rotation ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġanchor Node . anchor Ġ= Ġnew Anchor ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTemp or arily Ġset Ġthe Ġnode Ġto Ġthe Ġfinal Ġworld Ġrotation Ġso Ġthat Ġwe Ġcan Ġaccur ately ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdetermine Ġthe Ġinitial Forward In Local Ġin Ġthe Ġnew Ġcoordinate Ġspace . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransform able Node . world Rotation Ġ= Ġfinal Desired World Rotation ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinitial Forward In World Ġ= Ġtransform able Node . forward ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Forward In Local . set ( anchor Node . world ToLocal Direction ( initial Forward In World )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransform able Node . world Rotation Ġ= Ġworld Rotation ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransform able Node . world Position Ġ= Ġworld Position ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġdesired Local Position Ġ= ĠVector 3 . zero () ĊĠĠĠĠĠĠĠ Ġdesired Local Rotation Ġ= Ġcalculate Final Desired Local Rotation ( Quaternion . identity ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġanchor Node Or Die : ĠAnchor Node ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparent Ġ= Ġtransform able Node . parent ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( parent Ġis ĠAnchor Node ) Ġ{ Ġ" Transform able Node Ġmust Ġhave Ġan ĠAnchor Node Ġas Ġa Ġparent ." Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġparent ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Position ( frame Time : ĠFrame Time ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠStore Ġin Ġlocal Ġvariable Ġfor Ġnull ness Ġstatic Ġanalysis . ĊĠĠĠĠĠĠĠ Ġval Ġdesired Local Position Ġ= Ġdesired Local Position Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġvar Ġlocal Position Ġ= Ġtransform able Node . local Position ĊĠĠĠĠĠĠĠ Ġval Ġl erp Factor Ġ= ĠMath Helper . clamp ( frame Time . delta Seconds Ġ* ĠL ER P _ SPEED , Ġ 0 f , Ġ 1 f ) ĊĠĠĠĠĠĠĠ Ġlocal Position Ġ= ĠVector 3 . lerp ( local Position , Ġdesired Local Position , Ġl erp Factor ) ĊĠĠĠĠĠĠĠ Ġval Ġlength Diff Ġ= ĠMath . abs ( Vector 3 . subtract ( desired Local Position , Ġlocal Position ). length ()) ĊĠĠĠĠĠĠĠ Ġif Ġ( length Diff Ġ<= ĠPOSITION _ LENGTH _ THRESHOLD ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Position Ġ= Ġdesired Local Position ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . desired Local Position Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtransform able Node . local Position Ġ= Ġlocal Position ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Rotation ( frame Time : ĠFrame Time ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠStore Ġin Ġlocal Ġvariable Ġfor Ġnull ness Ġstatic Ġanalysis . ĊĠĠĠĠĠĠĠ Ġval Ġdesired Local Rotation Ġ= Ġdesired Local Rotation Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġvar Ġlocal Rotation Ġ= Ġtransform able Node . local Rotation ĊĠĠĠĠĠĠĠ Ġval Ġl erp Factor Ġ= ĠMath Helper . clamp ( frame Time . delta Seconds Ġ* ĠL ER P _ SPEED , Ġ 0 f , Ġ 1 f ) ĊĠĠĠĠĠĠĠ Ġlocal Rotation Ġ= ĠQuaternion . s lerp ( local Rotation , Ġdesired Local Rotation , Ġl erp Factor ) ĊĠĠĠĠĠĠĠ Ġval Ġdot Ġ= ĠMath . abs ( dot Quaternion ( local Rotation , Ġdesired Local Rotation )) ĊĠĠĠĠĠĠĠ Ġif Ġ( dot Ġ>= ĠROT ATION _ DOT _ THRESHOLD ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Rotation Ġ= Ġdesired Local Rotation ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . desired Local Rotation Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtransform able Node . local Rotation Ġ= Ġlocal Rotation ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠWhen Ġtrans lating , Ġthe Ġup Ġdirection Ġof Ġthe Ġnode Ġmust Ġmatch Ġthe Ġup Ġdirection Ġof Ġthe Ġplane Ġfrom ĊĠĠĠĠ Ġ* Ġthe Ġhit Ġresult . ĠHowever , Ġwe Ġalso Ġneed Ġto Ġmake Ġsure Ġthat Ġthe Ġoriginal Ġforward Ġdirection Ġof Ġthe ĊĠĠĠĠ Ġ* Ġnode Ġis Ġrespect ed . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcalculate Final Desired Local Rotation ( desired Local Rotation : ĠQuaternion ): ĠQuaternion Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠGet Ġa Ġrotation Ġjust Ġto Ġthe Ġup Ġdirection . ĊĠĠĠĠĠĠĠ Ġ// ĠOtherwise , Ġthe Ġnode Ġwill Ġspin Ġaround Ġas Ġyou Ġrotate . ĊĠĠĠĠĠĠĠ Ġvar Ġdesired Local Rotation Ġ= Ġdesired Local Rotation ĊĠĠĠĠĠĠĠ Ġval Ġrotated Up Ġ= ĠQuaternion . rotate Vector ( desired Local Rotation , ĠVector 3 . up ()) ĊĠĠĠĠĠĠĠ Ġdesired Local Rotation Ġ= ĠQuaternion . rotation Between Vectors ( Vector 3 . up (), Ġrotated Up ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAdjust Ġthe Ġrotation Ġto Ġmake Ġsure Ġthe Ġnode Ġmaintains Ġthe Ġsame Ġforward Ġdirection . ĊĠĠĠĠĠĠĠ Ġval Ġforward In Local Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠQuaternion . rotation Between Vectors ( Vector 3 . forward (), Ġinitial Forward In Local ) ĊĠĠĠĠĠĠĠ Ġdesired Local Rotation Ġ= ĠQuaternion . multiply ( desired Local Rotation , Ġforward In Local ) ĊĠĠĠĠĠĠĠ Ġreturn Ġdesired Local Rotation . normalized () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠL ER P _ SPEED Ġ= Ġ 1 2 . 0 f ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠPOSITION _ LENGTH _ THRESHOLD Ġ= Ġ 0 . 0 1 f ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠROT ATION _ DOT _ THRESHOLD Ġ= Ġ 0 . 9 9 f ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġdot Quaternion ( lhs : ĠQuaternion , Ġrhs : ĠQuaternion ): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġlhs . x Ġ* Ġrhs . x Ġ+ Ġlhs . y Ġ* Ġrhs . y Ġ+ Ġlhs . z Ġ* Ġrhs . z Ġ+ Ġlhs . w Ġ* Ġrhs . w ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }