1616
1717package com.example.xr.arcore
1818
19+ import android.app.Activity
1920import androidx.activity.ComponentActivity
2021import androidx.lifecycle.lifecycleScope
2122import androidx.xr.arcore.Hand
@@ -28,8 +29,10 @@ import androidx.xr.runtime.SessionConfigureSuccess
2829import androidx.xr.runtime.math.Pose
2930import androidx.xr.runtime.math.Quaternion
3031import androidx.xr.runtime.math.Vector3
32+ import androidx.xr.runtime.math.toRadians
3133import androidx.xr.scenecore.GltfModelEntity
3234import androidx.xr.scenecore.scene
35+ import kotlinx.coroutines.flow.Flow
3336import kotlinx.coroutines.launch
3437
3538@Suppress(" RestrictedApi" ) // b/416288516 - session.config and session.configure() are incorrectly restricted
@@ -65,6 +68,16 @@ fun ComponentActivity.collectHands(session: Session) {
6568 }
6669}
6770
71+ fun secondaryHandDetection (activity : Activity , session : Session ) {
72+ fun detectGesture (handState : Flow <Hand .State >) {}
73+ // [START androidxr_arcore_hand_handedness]
74+ val handedness = Hand .getHandedness(activity.contentResolver)
75+ val secondaryHand = if (handedness == Hand .Handedness .LEFT ) Hand .right(session) else Hand .left(session)
76+ val handState = secondaryHand?.state ? : return
77+ detectGesture(handState)
78+ // [END androidxr_arcore_hand_handedness]
79+ }
80+
6881fun ComponentActivity.renderPlanetAtHandPalm (leftHandState : Hand .State ) {
6982 val session: Session = null !!
7083 val palmEntity: GltfModelEntity = null !!
@@ -106,3 +119,27 @@ fun ComponentActivity.renderPlanetAtFingerTip(rightHandState: Hand.State) {
106119 indexFingerEntity.setPose(Pose (position, rotation))
107120 // [END androidxr_arcore_hand_entityAtIndexFingerTip]
108121}
122+
123+ private fun detectPinch (session : Session , handState : Hand .State ): Boolean {
124+ // [START androidxr_arcore_hand_pinch_gesture]
125+ val thumbTip = handState.handJoints[HandJointType .THUMB_TIP ] ? : return false
126+ val thumbTipPose = session.scene.perceptionSpace.transformPoseTo(thumbTip, session.scene.activitySpace)
127+ val indexTip = handState.handJoints[HandJointType .INDEX_TIP ] ? : return false
128+ val indexTipPose = session.scene.perceptionSpace.transformPoseTo(indexTip, session.scene.activitySpace)
129+ return Vector3 .distance(thumbTipPose.translation, indexTipPose.translation) < 0.05
130+ // [END androidxr_arcore_hand_pinch_gesture]
131+ }
132+
133+ private fun detectStop (session : Session , handState : Hand .State ): Boolean {
134+ // [START androidxr_arcore_hand_stop_gesture]
135+ val threshold = toRadians(angleInDegrees = 30f )
136+ fun pointingInSameDirection (joint1 : HandJointType , joint2 : HandJointType ): Boolean {
137+ val forward1 = handState.handJoints[joint1]?.forward ? : return false
138+ val forward2 = handState.handJoints[joint2]?.forward ? : return false
139+ return Vector3 .angleBetween(forward1, forward2) < threshold
140+ }
141+ return pointingInSameDirection(HandJointType .INDEX_PROXIMAL , HandJointType .INDEX_TIP ) &&
142+ pointingInSameDirection(HandJointType .MIDDLE_PROXIMAL , HandJointType .MIDDLE_TIP ) &&
143+ pointingInSameDirection(HandJointType .RING_PROXIMAL , HandJointType .RING_TIP )
144+ // [END androidxr_arcore_hand_stop_gesture]
145+ }
0 commit comments