Jetpack XR için ARCore, kullanıcının algılanan elleri hakkında bilgi sağlayabilir ve eller ile ilişkili eklemler için poz bilgisi verir. Bu el verileri, kullanıcının ellerine öğe ve model eklemek için kullanılabilir. Örneğin, bir araç menüsü:
Oturum alma
Android XR Session
ile el bilgilerine erişme Session
almak için Oturumun yaşam döngüsünü anlama başlıklı makaleyi inceleyin.
Oturumu yapılandırma
El takibi, XR oturumlarında varsayılan olarak etkin değildir. El verilerini almak için oturumu yapılandırın ve HandTrackingMode.BOTH
modunu ayarlayın:
val newConfig = session.config.copy( handTracking = Config.HandTrackingMode.BOTH ) when (val result = session.configure(newConfig)) { is SessionConfigureConfigurationNotSupported -> TODO(/* Some combinations of configurations are not valid. Handle this failure case. */) is SessionConfigureSuccess -> TODO(/* Success! */) else -> TODO(/* A different unhandled exception was thrown. */) }
El verilerini alma
El verileri, sol ve sağ eller için ayrı ayrı kullanılabilir. Her eklemin pozisyonlarına erişmek için her elin state
simgesini kullanın:
Hand.left(session)?.state?.collect { handState -> // or Hand.right(session) // Hand state has been updated. // Use the state of hand joints to update an entity's position. renderPlanetAtHandPalm(handState) }
Eller aşağıdaki özelliklere sahiptir:
trackingState
: Elin takip edilip edilmediği.handJoints
: El eklemlerinin pozlarla eşlendiği bir harita. El eklemi pozları, OpenXR standartları ile belirtilir.
Uygulamanızda el verilerini kullanma
Kullanıcının el eklemlerinin konumları, 3D nesneleri kullanıcının ellerine sabitlemek için kullanılabilir. Örneğin, bir modeli sol avuca eklemek için:
val palmPose = leftHandState.handJoints[HandJointType.PALM] ?: return // the down direction points in the same direction as the palm val angle = Vector3.angleBetween(palmPose.rotation * Vector3.Down, Vector3.Up) palmEntity.setEnabled(angle > Math.toRadians(40.0)) val transformedPose = session.scene.perceptionSpace.transformPoseTo( palmPose, session.scene.activitySpace, ) val newPosition = transformedPose.translation + transformedPose.down * 0.05f palmEntity.setPose(Pose(newPosition, transformedPose.rotation))
Dilerseniz modeli sağ elinizin işaret parmağı ucuna da ekleyebilirsiniz:
val tipPose = rightHandState.handJoints[HandJointType.INDEX_TIP] ?: return // the forward direction points towards the finger tip. val angle = Vector3.angleBetween(tipPose.rotation * Vector3.Forward, Vector3.Up) indexFingerEntity.setEnabled(angle > Math.toRadians(40.0)) val transformedPose = session.scene.perceptionSpace.transformPoseTo( tipPose, session.scene.activitySpace, ) val position = transformedPose.translation + transformedPose.forward * 0.03f val rotation = Quaternion.fromLookTowards(transformedPose.up, Vector3.Up) indexFingerEntity.setPose(Pose(position, rotation))
Temel el hareketlerini algılama
Temel el hareketlerini algılamak için eldeki eklemlerin pozlarını kullanır. Eklemlerin belirli bir poz olarak kaydedilmesi için hangi poz aralığında olması gerektiğini belirlemek üzere El eklemlerinin kuralları'na bakın.
Örneğin, başparmak ve işaret parmağıyla yapılan bir tutma hareketini algılamak için iki parmak ucu eklemi arasındaki mesafeyi kullanın:
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
Daha karmaşık bir hareket örneği "durdurma" hareketidir. Bu harekette her parmak uzatılmalı, yani her parmaktaki her eklem yaklaşık olarak aynı yöne bakmalıdır:
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)
El hareketleri için özel algılama geliştirirken aşağıdaki noktaları aklınızda bulundurun:
- Kullanıcılar, belirli bir hareketi farklı şekilde yorumlayabilir. Örneğin, bazıları "dur" hareketinde parmakların açık olmasını tercih ederken bazıları parmakların kapalı olmasını daha sezgisel bulabilir.
- Bazı hareketleri sürdürmek rahatsız edici olabilir. Kullanıcının ellerini yormayan sezgisel hareketler kullanın.
Kullanıcının ikincil elini belirleme
Android sistemi, sistem tercihlerinde kullanıcının belirttiği şekilde sistem gezinmesini kullanıcının birincil eline yerleştirir. Sistem gezinme hareketleriyle çakışmayı önlemek için özel hareketlerinizde ikincil elinizi kullanın:
val handedness = Hand.getPrimaryHandSide(activity.contentResolver) val secondaryHand = if (handedness == Hand.HandSide.LEFT) Hand.right(session) else Hand.left(session) val handState = secondaryHand?.state ?: return detectGesture(handState)
OpenXR™ ve OpenXR logosu, The Khronos Group Inc. şirketinin ticari markalarıdır ve Çin, Avrupa Birliği, Japonya ve Birleşik Krallık'ta ticari marka olarak tescillidir.