ShadowyLynx1866
19 days agoExplorer
Is there a simple way to increase the pointer distance ?
It seems the pointer max distance is limited. Is there a way to increase this value, in order to be able to select ui items from a panel that is very large or far away for example ? Thx
Ok, I digged into the meta scene sample and found a solution from what has been done in 'PremiumMediaSample'.
Create a new System that will look for collisions of your panel from controllers and dispatch back the hitInfo to the scene.
Here what I've done. Feel free to use it if it can help you.
package com.canal.android.quest.system import androidx.core.net.toUri import com.canal.ui.common.util.ALPHA_TRANSPARENT import com.meta.spatial.core.Color4 import com.meta.spatial.core.Entity import com.meta.spatial.core.Query import com.meta.spatial.core.SystemBase import com.meta.spatial.core.Vector3 import com.meta.spatial.runtime.PanelSceneObject import com.meta.spatial.toolkit.Controller import com.meta.spatial.toolkit.Transform import com.meta.spatial.core.Pose import com.meta.spatial.core.Quaternion import com.meta.spatial.runtime.AlphaMode import com.meta.spatial.runtime.ButtonBits import com.meta.spatial.toolkit.Material import com.meta.spatial.toolkit.Mesh import com.meta.spatial.toolkit.MeshCollision import com.meta.spatial.toolkit.Scale import com.meta.spatial.toolkit.Visible import com.meta.spatial.vr.KPOINTER_DISTANCE class PointerInfoSystem( private val panel: PanelSceneObject, ) : SystemBase() { private var lastTime = System.currentTimeMillis() // Create a mesh that will be displayed as a cursor private val pointer3dEntity = Entity.create( listOf( Mesh("apk:///scenes/sphere.glb".toUri(), hittable = MeshCollision.NoCollision), Transform(Pose()), Scale(0.1f) ), ) override fun execute() { val currentTime = System.currentTimeMillis() lastTime = currentTime val controllerEntities = Query.where { has(Controller.id) }.eval().filter { it.isLocal() } for (controllerEntity in controllerEntities) { val controller = controllerEntity.getComponent<Controller>() if (!controller.isActive) continue val controllerPose = controllerEntity.getComponent<Transform>().transform val worldOrigin = controllerPose.t // Set your new max distance you want to interact with val worldTarget = controllerPose * Vector3(0.0f, 0.0f, MAX_POINTER_DISTANCE) // check for a collision with the scene getScene().lineSegmentIntersect(worldOrigin, worldTarget)?.let { hitInfo -> // Use 3D pointer only if further than max default pointer distance if (hitInfo.distance > KPOINTER_DISTANCE) { // Check if collisions with Panel happens val i**bleep**tingPanel = hitInfo.entity != null && hitInfo.entity == panel.entity // Do some visual feeback when you are clicking val scale = if (controller.isClicking()) 0.08f else 0.1f // Add pointer to Panel val pointer3dPose = Pose(hitInfo.point, Quaternion.lookRotation(hitInfo.normal.normalize())) pointer3dEntity.setComponents( listOf( Transform(pointer3dPose), Scale(scale), Visible(i**bleep**tingPanel), ), ) // Dispatch hitInfo to scene to be able to interact with Panel if (i**bleep**tingPanel) { getScene().onInput(hitInfo, controllerEntity, controller.changedButtons, controller.buttonState) } } } } } private fun Controller.isClicking(): Boolean { // true if the controller is currently pressing the A button return (buttonState and ButtonBits.ButtonA) != 0 || // true if the controller is currently holding down either of the triggers (buttonState and (ButtonBits.ButtonTriggerL or ButtonBits.ButtonTriggerR)) != 0 } private companion object { // max distance to ray cast into the scene for a contact private const val MAX_POINTER_DISTANCE = 100f } }