Android 使用手势或触摸事件场景旋转节点形成核心

Android 使用手势或触摸事件场景旋转节点形成核心,android,arcore,sceneform,Android,Arcore,Sceneform,我在应用程序中使用AR Core作为3D查看器。我不是使用Sceneform进行AR渲染,而是在3D中渲染模型。我面临的问题是如何通过滑动手势或触摸事件360度旋转模型。使用sceneform是否可能,或者我需要使用更困难的方法,如OpenGL 这是我的密码 public class FullDegreeActivity extends AppCompatActivity { SceneView sceneView; Scene scene; Node node; @Override pro

我在应用程序中使用AR Core作为3D查看器。我不是使用Sceneform进行AR渲染,而是在3D中渲染模型。我面临的问题是如何通过滑动手势或触摸事件360度旋转模型。使用sceneform是否可能,或者我需要使用更困难的方法,如OpenGL

这是我的密码

public class FullDegreeActivity extends AppCompatActivity {

SceneView sceneView;
Scene scene;
Node node;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_full_degree);
    inIt();
    renderObject();
}

private void inIt() {
    sceneView = findViewById(R.id.scene_view);
    scene = sceneView.getScene();
}

private void renderObject() {
    ModelRenderable.builder().setSource(this, Uri.parse("edited.sfb"))
            .build().thenAccept(modelRenderable -> {
                addNodeToScene(modelRenderable);
            }
    ).exceptionally(throwable -> {

        return null;
    });
}

private void addNodeToScene(ModelRenderable renderable) {
    node = new Node();
    node.setParent(scene);
    node.setLocalPosition(new Vector3(0f, 0f, -1f));
    node.setLocalScale(new Vector3(1f, 1f, 1f));
    node.setName("Dog");
    node.setRenderable(renderable);
    TransformableNode transformableNode = new TransformableNode(sceneView.getTransformationSystem());
    transformableNode.setParent(node);
    transformableNode.setLocalRotation(Quaternion.axisAngle(new Vector3(1f, 0, 0), 0f));
    transformableNode.setRenderable(renderable);
    transformableNode.select();
    scene.addChild(transformableNode);
}

@Override
protected void onPause() {
    super.onPause();
    sceneView.pause();
}

@Override
protected void onResume() {
    super.onResume();
    try {
        sceneView.resume();
    } catch (CameraNotAvailableException e) {
        e.printStackTrace();
    }
}
}

使用Sceneform可以轻松地完成此操作。事实上,您不需要为它设置任何场景格式代码。您只需使用Android的标准手势识别来检测手势,并使用它来更新节点的旋转

我认为您的实现非常接近它应该如何工作。请看一下Google()的hellosceneform示例。

我分享了我的新体验,也许有人仍然需要解决方案

要实现这一目标,您有两种选择:

  • 如上所述,您可以实现自己的手势、缩放和旋转 使用androids标准手势或场景的附加PeekTouchListener

  • 将Transformable node用于其设施,然后只需移除平移控制器并实现新的旋转控制器

  • 让我们考虑Kotlin代码

    位细节中的选项2 为拖动手势装入新的旋转控制器:

    class DragRotationController(transformableNode: BaseTransformableNode, gestureRecognizer: DragGestureRecognizer) :
        BaseTransformationController<DragGesture>(transformableNode, gestureRecognizer) {
    
        // Rate that the node rotates in degrees per degree of twisting.
        var rotationRateDegrees = 0.5f
    
        public override fun canStartTransformation(gesture: DragGesture): Boolean {
            return transformableNode.isSelected
        }
    
        public override fun onContinueTransformation(gesture: DragGesture) {
    
            var localRotation = transformableNode.localRotation
    
            val rotationAmountX = gesture.delta.x * rotationRateDegrees
            val rotationDeltaX = Quaternion(Vector3.up(), rotationAmountX)
            localRotation = Quaternion.multiply(localRotation, rotationDeltaX)
    
            transformableNode.localRotation = localRotation
        }
    
        public override fun onEndTransformation(gesture: DragGesture) {}
    }
    
    将自定义旋转控制器添加到节点

    val dragRotationController = DragRotationController(node, transformationSystem.dragRecognizer)
    node.addTransformationController(dragRotationController)
    
    这是牵引力转换电极

    import com.google.ar.sceneform.ux.TransformableNode
    import com.google.ar.sceneform.ux.TransformationSystem
    
    class DragTransformableNode(transformationSystem: TransformationSystem) :
        TransformableNode(transformationSystem) {
    
        private val dragRotationController = DragRotationController(
            this,
            transformationSystem.dragRecognizer
        )
    
        init {
            translationController.isEnabled = false
            removeTransformationController(translationController)
            removeTransformationController(rotationController)
            addTransformationController(dragRotationController)
        }
    }
    

    这似乎不起作用。找不到addTransformationController方法。@NoumanCh您的节点必须是TransformableNode才能有addTransformationController方法我们有一个用于TransformableNode的addTransformChangedListener,但没有addTransformationController。@NoumanCh是的,它在BaseTranformableNode中保护了函数,您必须从TransformableNode进行扩展和实现,正如我在DragRotationController中所做的那样,我将更新我的答案。嘿,我已将DragTransformableNode cod附加到我的答案中。您是否有解决方案,我对此感到困惑?如果您能分享详细信息,将非常有帮助
    import com.google.ar.sceneform.ux.TransformableNode
    import com.google.ar.sceneform.ux.TransformationSystem
    
    class DragTransformableNode(transformationSystem: TransformationSystem) :
        TransformableNode(transformationSystem) {
    
        private val dragRotationController = DragRotationController(
            this,
            transformationSystem.dragRecognizer
        )
    
        init {
            translationController.isEnabled = false
            removeTransformationController(translationController)
            removeTransformationController(rotationController)
            addTransformationController(dragRotationController)
        }
    }