Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed tap events #96

Merged
merged 3 commits into from Jun 17, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
57 changes: 25 additions & 32 deletions arsceneview/src/main/java/io/github/sceneview/ar/ArSceneView.kt
Expand Up @@ -3,7 +3,6 @@ package io.github.sceneview.ar
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.lifecycle.*
import com.google.ar.core.*
import com.google.ar.core.CameraConfig.FacingDirection
import com.google.ar.sceneform.ArCamera
Expand All @@ -13,9 +12,11 @@ import io.github.sceneview.ar.arcore.*
import io.github.sceneview.ar.camera.ArCameraStream
import io.github.sceneview.ar.interaction.ArNodeManipulator
import io.github.sceneview.ar.interaction.ArSceneGestureDetector
import io.github.sceneview.ar.node.ArNode
import io.github.sceneview.ar.scene.PlaneRenderer
import io.github.sceneview.interaction.SceneGestureDetector
import io.github.sceneview.node.Node
import io.github.sceneview.renderable.Renderable
import io.github.sceneview.utils.FrameTime
import io.github.sceneview.utils.setKeepScreenOn

Expand Down Expand Up @@ -260,21 +261,19 @@ open class ArSceneView @JvmOverloads constructor(
var onArFrame: ((arFrame: ArFrame) -> Unit)? = null

/**
* ### Invoked when an ARCore plane is tapped
* ### Invoked when an ARCore trackable is tapped
*
* Registers a callback to be invoked when an ARCore [Trackable] is tapped.
* Depending on the session config you defined, the [HitResult.getTrackable] can be:
* - a [Plane] if [ArSession.planeFindingEnabled]
* - an [InstantPlacementPoint] if [ArSession.instantPlacementEnabled]
* - a [DepthPoint] if [ArSession.depthEnabled]
* Depending on the session configuration the [HitResult.getTrackable] can be:
* - A [Plane] if [ArSession.planeFindingEnabled].
* - An [InstantPlacementPoint] if [ArSession.instantPlacementEnabled].
* - A [DepthPoint] and [Point] if [ArSession.depthEnabled].
*
* The callback will only be invoked if no [com.google.ar.sceneform.Node] was tapped.
* The listener is only invoked if no node is tapped.
*
* - hitResult: The ARCore hit result that occurred when tapping the plane
* - motionEvent: the motion event that triggered the tap
* - `hitResult` - The ARCore hit result for the trackable that was tapped.
* - `motionEvent` - The motion event that caused the tap.
*/
var onTouchAr: ((hitResult: HitResult, motionEvent: MotionEvent) -> Unit)? =
null
var onTapAr: ((hitResult: HitResult, motionEvent: MotionEvent) -> Unit)? = null

/**
* ### Invoked when an ARCore AugmentedImage TrackingState/TrackingMethod is updated
Expand Down Expand Up @@ -417,38 +416,32 @@ open class ArSceneView @JvmOverloads constructor(
}
}

override fun onTouch(selectedNode: Node?, motionEvent: MotionEvent): Boolean {
// TODO : Should be handled by the nodesTouchEventDispatcher
//nodeGestureRecognizer.onNodeTap(null)
override fun onTap(node: Node?, renderable: Renderable, motionEvent: MotionEvent) {
super.onTap(node, renderable, motionEvent)

arSession?.let { session ->
session.currentFrame?.hitTest(motionEvent)?.let { hitResult ->
onTouchAr(hitResult, motionEvent)
return true
gestureDetector.selectedNode = node as? ArNode
grassydragon marked this conversation as resolved.
Show resolved Hide resolved

if (node == null) {
arSession?.currentFrame?.hitTest(motionEvent)?.let { hitResult ->
onTapAr(hitResult, motionEvent)
}
}
return false
}

/**
* ### Invoked when an ARCore [Trackable] is tapped
* ### Invoked when an ARCore trackable is tapped
*
* The callback will only be invoked if **no** [com.google.ar.sceneform.Node] was tapped.
* Calls the `onTapAr` listener if it is available.
*
* - hitResult: The ARCore hit result that occurred when tapping the plane
* - plane: The ARCore Plane that was tapped
* - motionEvent: the motion event that triggered the tap
* @param hitResult The ARCore hit result for the trackable that was tapped.
* @param motionEvent The motion event that caused the tap.
*/
protected open fun onTouchAr(hitResult: HitResult, motionEvent: MotionEvent) {
onTouchAr?.invoke(hitResult, motionEvent)
open fun onTapAr(hitResult: HitResult, motionEvent: MotionEvent) {
onTapAr?.invoke(hitResult, motionEvent)
}

open class DefaultArSceneGestureListener(sceneView: SceneView) :
SceneView.DefaultSceneGestureListener(sceneView) {
override fun onSingleTapUp(e: MotionEvent): Boolean {
return sceneView.onTouch(null, e)
}
}
SceneView.DefaultSceneGestureListener(sceneView)
}

/**
Expand Down
Expand Up @@ -31,10 +31,6 @@ open class ArNodeManipulator(
open val selectedNodeVisualizer: SelectedNodeVisualizer
get() = sceneView.selectedNodeVisualizer

open fun onNodeTouch(node: Node) {
selectedNode = node as? ArNode
}

open fun beginTransform(): Boolean =
selectedNode?.takeIf {
currentGestureTransform == null && it.positionEditable
Expand Down
Expand Up @@ -2,6 +2,7 @@ package io.github.sceneview.ar.interaction

import android.view.ScaleGestureDetector
import io.github.sceneview.ar.ArSceneView
import io.github.sceneview.ar.node.ArNode
import io.github.sceneview.interaction.MoveGestureDetector
import io.github.sceneview.interaction.RotateGestureDetector
import io.github.sceneview.interaction.SceneGestureDetector
Expand All @@ -13,6 +14,12 @@ class ArSceneGestureDetector(
val nodeManipulator: ArNodeManipulator? = ArNodeManipulator(sceneView)
) : SceneGestureDetector(sceneView = sceneView, listener = listener, cameraManipulator = null) {

var selectedNode: ArNode?
get() = nodeManipulator?.selectedNode
set(value) {
nodeManipulator?.selectedNode = value
}

private val moveListener = object : MoveGestureDetector.OnMoveGestureListener {
override fun onMoveBegin(detector: MoveGestureDetector): Boolean {
val listenerResult = listener?.onMoveBegin(detector) ?: false
Expand Down Expand Up @@ -60,6 +67,7 @@ class ArSceneGestureDetector(
nodeManipulator?.endRotate()
}
}

private val scaleListener = object : ScaleGestureDetector.OnScaleGestureListener {
override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
return listOfNotNull(
Expand Down Expand Up @@ -87,9 +95,4 @@ class ArSceneGestureDetector(
RotateGestureDetector(sceneView.context, rotateListener)
override var scaleGestureDetector: ScaleGestureDetector? =
ScaleGestureDetector(sceneView.context, scaleListener)

override fun onTouchNode(selectedNode: Node): Boolean {
nodeManipulator?.onNodeTouch(selectedNode)
return nodeManipulator != null
}
}
Expand Up @@ -53,7 +53,7 @@ class MainFragment : Fragment(R.layout.fragment_main) {
modelNode.scaleModel(units = 1.0f)
sceneView.addChild(modelNode)
}
onTouchAr = { hitResult, _ ->
onTapAr = { hitResult, _ ->
anchorOrMove(hitResult.createAnchor())
}
}
Expand Down
Expand Up @@ -61,9 +61,10 @@ class MainFragment : Fragment(R.layout.fragment_main) {
}
editableTransforms = EditableTransform.ALL
}
sceneView.addChild(modelNode)
// Quick workaround until the Node Pick is fixed
sceneView.gestureDetector.onTouchNode(modelNode)
sceneView.apply {
addChild(modelNode)
gestureDetector.selectedNode = modelNode
grassydragon marked this conversation as resolved.
Show resolved Hide resolved
}
}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
Expand Down