diff --git a/xr/src/main/java/com/example/xr/arcore/Hands.kt b/xr/src/main/java/com/example/xr/arcore/Hands.kt index af3a547b0..13346b202 100644 --- a/xr/src/main/java/com/example/xr/arcore/Hands.kt +++ b/xr/src/main/java/com/example/xr/arcore/Hands.kt @@ -16,6 +16,7 @@ package com.example.xr.arcore +import android.app.Activity import androidx.activity.ComponentActivity import androidx.lifecycle.lifecycleScope import androidx.xr.arcore.Hand @@ -28,8 +29,10 @@ import androidx.xr.runtime.SessionConfigureSuccess import androidx.xr.runtime.math.Pose import androidx.xr.runtime.math.Quaternion import androidx.xr.runtime.math.Vector3 +import androidx.xr.runtime.math.toRadians import androidx.xr.scenecore.GltfModelEntity import androidx.xr.scenecore.scene +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch @Suppress("RestrictedApi") // b/416288516 - session.config and session.configure() are incorrectly restricted @@ -65,6 +68,16 @@ fun ComponentActivity.collectHands(session: Session) { } } +fun secondaryHandDetection(activity: Activity, session: Session) { + fun detectGesture(handState: Flow) {} + // [START androidxr_arcore_hand_handedness] + val handedness = Hand.getHandedness(activity.contentResolver) + val secondaryHand = if (handedness == Hand.Handedness.LEFT) Hand.right(session) else Hand.left(session) + val handState = secondaryHand?.state ?: return + detectGesture(handState) + // [END androidxr_arcore_hand_handedness] +} + fun ComponentActivity.renderPlanetAtHandPalm(leftHandState: Hand.State) { val session: Session = null!! val palmEntity: GltfModelEntity = null!! @@ -106,3 +119,27 @@ fun ComponentActivity.renderPlanetAtFingerTip(rightHandState: Hand.State) { indexFingerEntity.setPose(Pose(position, rotation)) // [END androidxr_arcore_hand_entityAtIndexFingerTip] } + +private fun detectPinch(session: Session, handState: Hand.State): Boolean { + // [START androidxr_arcore_hand_pinch_gesture] + val thumbTip = handState.handJoints[HandJointType.THUMB_TIP] ?: return false + val thumbTipPose = session.scene.perceptionSpace.transformPoseTo(thumbTip, session.scene.activitySpace) + val indexTip = handState.handJoints[HandJointType.INDEX_TIP] ?: return false + val indexTipPose = session.scene.perceptionSpace.transformPoseTo(indexTip, session.scene.activitySpace) + return Vector3.distance(thumbTipPose.translation, indexTipPose.translation) < 0.05 + // [END androidxr_arcore_hand_pinch_gesture] +} + +private fun detectStop(session: Session, handState: Hand.State): Boolean { + // [START androidxr_arcore_hand_stop_gesture] + val threshold = toRadians(angleInDegrees = 30f) + fun pointingInSameDirection(joint1: HandJointType, joint2: HandJointType): Boolean { + val forward1 = handState.handJoints[joint1]?.forward ?: return false + val forward2 = handState.handJoints[joint2]?.forward ?: return false + return Vector3.angleBetween(forward1, forward2) < threshold + } + return pointingInSameDirection(HandJointType.INDEX_PROXIMAL, HandJointType.INDEX_TIP) && + pointingInSameDirection(HandJointType.MIDDLE_PROXIMAL, HandJointType.MIDDLE_TIP) && + pointingInSameDirection(HandJointType.RING_PROXIMAL, HandJointType.RING_TIP) + // [END androidxr_arcore_hand_stop_gesture] +}