From 37701cfdd53fc641ea1d114b4254eb538c5c4338 Mon Sep 17 00:00:00 2001 From: Jan Szymanski Date: Sun, 21 Jun 2020 20:29:55 +0100 Subject: [PATCH] Implement 3D rotation --- .../magmolecular/ar/MagMolFragment.kt | 28 ++++++++++++------- .../ar/sceneform/ux/RotationController.java | 8 ++++-- .../sceneform/ux/TranslationController.java | 26 ++--------------- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/com/plweegie/magmolecular/ar/MagMolFragment.kt b/app/src/main/java/com/plweegie/magmolecular/ar/MagMolFragment.kt index ee19ef7..6c30ad5 100644 --- a/app/src/main/java/com/plweegie/magmolecular/ar/MagMolFragment.kt +++ b/app/src/main/java/com/plweegie/magmolecular/ar/MagMolFragment.kt @@ -9,6 +9,7 @@ import android.view.ViewGroup import com.google.ar.sceneform.math.Quaternion import com.google.ar.sceneform.math.Vector3 import com.google.ar.sceneform.ux.* +import kotlin.math.abs class MagMolFragment : ArFragment() { @@ -50,29 +51,36 @@ class MagMolFragment : ArFragment() { var endPosition = Vector3.zero() it.setGestureEventListener(object : BaseGesture.OnGestureEventListener { - override fun onUpdated(gesture: DragGesture?) { - endPosition = gesture?.position - val angle = getRotationAngle(startPosition, endPosition) + override fun onUpdated(gesture: DragGesture) { + endPosition = gesture.position - gesture?.targetNode?.parent?.localRotation = Quaternion.multiply( - gesture?.targetNode?.parent?.localRotation, - Quaternion.axisAngle(Vector3.up().scaled(4.0f), angle) + gesture.targetNode?.parent?.localRotation = Quaternion.multiply( + gesture.targetNode?.parent?.localRotation, + getRotation(startPosition, endPosition) ) } - override fun onFinished(gesture: DragGesture?) {} + override fun onFinished(gesture: DragGesture) {} }) } + transformationSystem.apply { addGestureRecognizer(dragGestureRecognizer) + //addGestureRecognizer(twistGestureRecognizer) selectionVisualizer = NullVisualizer() } return transformationSystem } - private fun getRotationAngle(startPosition: Vector3, endPosition: Vector3): Float { - val diff = endPosition.x - startPosition.x - return (10 * diff) / displayMetrics.widthPixels + private fun getRotation(startPosition: Vector3, endPosition: Vector3): Quaternion { + val diffX = (endPosition.x - startPosition.x) + val diffY = (endPosition.y - startPosition.y) + + return if (abs(diffX) >= abs(diffY)) { + Quaternion.axisAngle(Vector3.up().scaled(40.0f), diffX / displayMetrics.widthPixels) + } else { + Quaternion.axisAngle(Vector3.right().scaled(40.0f), diffY / displayMetrics.heightPixels) + } } class NullVisualizer : SelectionVisualizer { diff --git a/sceneformux/ux/src/main/java/com/google/ar/sceneform/ux/RotationController.java b/sceneformux/ux/src/main/java/com/google/ar/sceneform/ux/RotationController.java index a7761cd..93b43a2 100644 --- a/sceneformux/ux/src/main/java/com/google/ar/sceneform/ux/RotationController.java +++ b/sceneformux/ux/src/main/java/com/google/ar/sceneform/ux/RotationController.java @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * Modifications (C) 2020 Jan K Szymanski */ package com.google.ar.sceneform.ux; @@ -25,7 +27,7 @@ public class RotationController extends BaseTransformationController { // Rate that the node rotates in degrees per degree of twisting. - private float rotationRateDegrees = 2.5f; + private float rotationRateDegrees = 1.0f; public RotationController( BaseTransformableNode transformableNode, TwistGestureRecognizer gestureRecognizer) { @@ -42,13 +44,13 @@ public float getRotationRateDegrees() { @Override public boolean canStartTransformation(TwistGesture gesture) { - return getTransformableNode().isSelected(); + return true; } @Override public void onContinueTransformation(TwistGesture gesture) { float rotationAmount = -gesture.getDeltaRotationDegrees() * rotationRateDegrees; - Quaternion rotationDelta = new Quaternion(Vector3.up(), rotationAmount); + Quaternion rotationDelta = new Quaternion(Vector3.forward(), rotationAmount); Quaternion localrotation = getTransformableNode().getLocalRotation(); localrotation = Quaternion.multiply(localrotation, rotationDelta); getTransformableNode().setLocalRotation(localrotation); diff --git a/sceneformux/ux/src/main/java/com/google/ar/sceneform/ux/TranslationController.java b/sceneformux/ux/src/main/java/com/google/ar/sceneform/ux/TranslationController.java index 6475849..8891826 100644 --- a/sceneformux/ux/src/main/java/com/google/ar/sceneform/ux/TranslationController.java +++ b/sceneformux/ux/src/main/java/com/google/ar/sceneform/ux/TranslationController.java @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * Modifications (C) 2020 Jan K Szymanski */ package com.google.ar.sceneform.ux; @@ -87,29 +89,7 @@ public boolean isTransforming() { @Override public boolean canStartTransformation(DragGesture gesture) { - Node targetNode = gesture.getTargetNode(); - if (targetNode == null) { - return false; - } - - BaseTransformableNode transformableNode = getTransformableNode(); - if (targetNode != transformableNode && !targetNode.isDescendantOf(transformableNode)) { - return false; - } - - if (!transformableNode.isSelected() && !transformableNode.select()) { - return false; - } - - Vector3 initialForwardInWorld = transformableNode.getForward(); - Node parent = transformableNode.getParent(); - if (parent != null) { - initialForwardInLocal.set(parent.worldToLocalDirection(initialForwardInWorld)); - } else { - initialForwardInLocal.set(initialForwardInWorld); - } - - return true; + return false; } @Override