How to disable surface detection in ARCore Android

2019-07-21 01:44发布

问题:

I am working on a project and facing an issue with ARCore. I used ARCore Location in my project, I set the location of object using latitude and longitude. but when I see it in the device, object location varies in AR.

CompletableFuture<ViewRenderable> exampleLayout = ViewRenderable.builder()
                    .setView(this, R.layout.example_layout)
                    .build();

    // When you build a Renderable, Sceneform loads its resources in the background while returning
    // a CompletableFuture. Call thenAccept(), handle(), or check isDone() before calling get().
    CompletableFuture<ModelRenderable> andy = ModelRenderable.builder()
            .setSource(this, R.raw.andy)
            .build();


    CompletableFuture.allOf(
            exampleLayout,
            andy)
            .handle(
                    (notUsed, throwable) -> {
                        // When you build a Renderable, Sceneform loads its resources in the background while
                        // returning a CompletableFuture. Call handle(), thenAccept(), or check isDone()
                        // before calling get().

                        if (throwable != null) {
                            DemoUtils.displayError(this, "Unable to load renderables", throwable);
                            return null;
                        }

                        try {
                            exampleLayoutRenderable = exampleLayout.get();
                            andyRenderable = andy.get();
                            hasFinishedLoading = true;

                        } catch (InterruptedException | ExecutionException ex) {
                            DemoUtils.displayError(this, "Unable to load renderables", ex);
                        }

                        return null;
                    });

    // Set an update listener on the Scene that will hide the loading message once a Plane is
    // detected.
    arSceneView
            .getScene()
            .setOnUpdateListener(
                    frameTime -> {
                        if (!hasFinishedLoading) {
                            return;
                        }

                        if (locationScene == null) {
                            // If our locationScene object hasn't been setup yet, this is a good time to do it
                            // We know that here, the AR components have been initiated.
                            locationScene = new LocationScene(this, this, arSceneView);

                            // Now lets create our location markers.
                            // First, a layout
                            LocationMarker layoutLocationMarker = new LocationMarker(
                                    77.398151,
                                    28.540926,
                                    getExampleView()
                            );

                            // An example "onRender" event, called every frame
                            // Updates the layout with the markers distance
                            layoutLocationMarker.setRenderEvent(new LocationNodeRender() {
                                @SuppressLint("SetTextI18n")
                                @Override
                                public void render(LocationNode node) {
                                    View eView = exampleLayoutRenderable.getView();
                                    TextView distanceTextView = eView.findViewById(R.id.textView2);
                                    distanceTextView.setText(node.getDistance() + "M");
                                }
                            });
                            // Adding the marker
                            locationScene.mLocationMarkers.add(layoutLocationMarker);

                            // Adding a simple location marker of a 3D model
                            locationScene.mLocationMarkers.add(
                                    new LocationMarker(
                                            77.398151,
                                            28.540926,
                                            getAndy()));
                        }

                        Frame frame = arSceneView.getArFrame();
                        if (frame == null) {
                            return;
                        }

                        if (frame.getCamera().getTrackingState() != TrackingState.TRACKING) {
                            return;
                        }

                        if (locationScene != null) {
                            locationScene.processFrame(frame);
                        }

                        if (loadingMessageSnackbar != null) {
                            for (Plane plane : frame.getUpdatedTrackables(Plane.class)) {
                                if (plane.getTrackingState() == TrackingState.TRACKING) {
                                    hideLoadingMessage();
                                }
                            }
                        }
                    });


    // Lastly request CAMERA & fine location permission which is required by ARCore-Location.
    ARLocationPermissionHelper.requestPermission(this);

The major problem in this is that it detects surface and place image according to that, If there is any possibility to disable surface detection in this then it works perfectly.

回答1:

Modify the session configuration with EnablePlaneFinding = false and then disable and reenable the ARCoreSession. That would disable plane finding but would keep existing planes as they were at the moment.

If you don't want to disable the session you could force an OnEnable() call on the session without disabling it:

 var session = GameObject.Find("ARCore Device").GetComponent<ARCoreSession>(); 
session.SessionConfig.EnablePlaneFinding = false; session.OnEnable();