16
16
17
17
package com.example.xr.arcore
18
18
19
+ import android.app.Activity
19
20
import androidx.activity.ComponentActivity
20
21
import androidx.lifecycle.lifecycleScope
21
22
import androidx.xr.arcore.Hand
@@ -28,8 +29,10 @@ import androidx.xr.runtime.SessionConfigureSuccess
28
29
import androidx.xr.runtime.math.Pose
29
30
import androidx.xr.runtime.math.Quaternion
30
31
import androidx.xr.runtime.math.Vector3
32
+ import androidx.xr.runtime.math.toRadians
31
33
import androidx.xr.scenecore.GltfModelEntity
32
34
import androidx.xr.scenecore.scene
35
+ import kotlinx.coroutines.flow.Flow
33
36
import kotlinx.coroutines.launch
34
37
35
38
@Suppress(" RestrictedApi" ) // b/416288516 - session.config and session.configure() are incorrectly restricted
@@ -65,6 +68,16 @@ fun ComponentActivity.collectHands(session: Session) {
65
68
}
66
69
}
67
70
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
+
68
81
fun ComponentActivity.renderPlanetAtHandPalm (leftHandState : Hand .State ) {
69
82
val session: Session = null !!
70
83
val palmEntity: GltfModelEntity = null !!
@@ -106,3 +119,27 @@ fun ComponentActivity.renderPlanetAtFingerTip(rightHandState: Hand.State) {
106
119
indexFingerEntity.setPose(Pose (position, rotation))
107
120
// [END androidxr_arcore_hand_entityAtIndexFingerTip]
108
121
}
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