旋转摄像头时,摄像头中的LocationMarkers呈现问题,并且在横向摄像头模式下也无法正常运行ViewRenderable

时间:2019-06-06 05:57:41

标签: android arcore

我正在研究ARCore Google提供库。因为我需要将现实世界中的位置标记放置在相机中,所以我使用了ARCore库的LocationMarker类和其他LocationScene类,还创建了ViewRenderable来创建自定义视图可渲染,并将其放置在特定的LatLong中,但是我遇到的问题是,标记在移动相机时会不断渲染,并且在横向模式下无法正常工作。

在将设备从纵向模式旋转到横向模式时,放置在现实世界中的标记会不断渲染,并且在特定位置处不稳定。

在下面,我发布我的代码。

private void loadMarkers(List<LatLngLocation> latLngList) {

    // clear the completable future map while again load the markers
    completableFutureMap.clear();

    // dynamic markers creation as per the list of latlng
    markersViewRenderables = new CompletableFuture[latLngList.size()];

    // create completableFuturemap for markers rending in location scene and put in to the map for manage
    for (int i = 0; i < latLngList.size(); i++) {
        LatLngLocation latlongLocation = latLngList.get(i);
        CompletableFuture<ViewRenderable> completableFuture = null;
        completableFuture = ViewRenderable.builder().setView(this, R.layout.location_marker_custom_view).build();
        completableFutureMap.put(latlongLocation.getId(), completableFuture);
        markersViewRenderables[i] = completableFuture;

    }

    // load all the completable viewrenderables
    CompletableFuture.allOf(
            markersViewRenderables)
            .handle(
                    (notUsed, throwable) -> {

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

                        hasFinishedLoading = true;

                        return null;
                    });


    // update the markers while camera moves and refresh the markers
    sceneform_ar_scene_view.getArSceneView()
            .getScene()
            .addOnUpdateListener(
                    frameTime -> {
                        if (!hasFinishedLoading) {
                            return;
                        }

                        hideSpinner();

                        // while first time creating the markers
                        if (locationScene == null && !isLoadedMarkers) {

                            Location deviceLocation = new Location("provider");
                            deviceLocation.setLatitude(Double.parseDouble(PrefHelper.getInstance().getString(PrefHelper.DEVICE_LATITUDE, "")));
                            deviceLocation.setLongitude(Double.parseDouble(PrefHelper.getInstance().getString(PrefHelper.DEVICE_LONGITUDE, "")));
                            locationScene = new LocationScene(this, this, sceneform_ar_scene_view.getArSceneView());
                            locationScene.deviceLocation.currentBestLocation = deviceLocation;


                            // create location markers of the inbuilt class
                            for (int i = 0; i < latLngList.size(); i++) {

                                LatLngLocation latLngLocation = latLngList.get(i);
                                CompletableFuture<ViewRenderable> completableFuture = completableFutureMap.get(latLngLocation.getId());
                                Location destLocation = new Location("provider");
                                destLocation.setLatitude(latLngLocation.getLatLng().latitude);
                                destLocation.setLongitude(latLngLocation.getLatLng().longitude);
                                LocationMarker locationMarker = new LocationMarker(latLngLocation.getLatLng().latitude, latLngLocation.getLatLng().longitude, new Node());

                                ViewRenderable viewRenderable = null;

                                try {
                                    viewRenderable = completableFuture.get();
                                    viewRenderable.setSizer(new DpToMetersViewSizer(getResources().getDimensionPixelOffset(R.dimen._200sdp)));
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                } catch (ExecutionException e) {
                                    e.printStackTrace();
                                }
                                locationMarker.node.setRenderable(viewRenderable);

                                TextView tvLocationDistance = viewRenderable.getView().findViewById(R.id.tvLocationDistance);
                                TextView tvLocationName = viewRenderable.getView().findViewById(R.id.tvLocationName);

                                double distance = deviceLocation.distanceTo(destLocation);
                                double distance_in_km = distance / 1000;

                                tvLocationName.setText(latLngLocation.getLocationName());
                                tvLocationDistance.setText(String.format(Locale.ENGLISH, "%.2f KM", distance_in_km));

                                locationScene.mLocationMarkers.add(locationMarker);

                                isLoadedMarkers = true;
                            }
                        }

                        // get the arframe of arcamera
                        Frame frame = sceneform_ar_scene_view.getArSceneView().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();
                                }
                            }
                        }
                    });

    ARLocationPermissionHelper.requestPermission(this);

}

并且在locationMarker结果正确之后,我还对LocationScene类进行了自定义更改

if (((LocationMarker) this.mLocationMarkers.get(i)).anchorNode != null && ((LocationMarker) this.mLocationMarkers.get(i)).anchorNode.getAnchor() != null) {
                        ((LocationMarker) this.mLocationMarkers.get(i)).anchorNode.getAnchor().detach();
                    }

                    Anchor newAnchor = this.mSession.createAnchor(frame.getCamera().getDisplayOrientedPose().compose(Pose.makeTranslation(xRotated, y + (float) heightAdjustment, zRotated)));
                    ((LocationMarker) this.mLocationMarkers.get(i)).anchorNode = new LocationNode(newAnchor, (LocationMarker) this.mLocationMarkers.get(i), this);
                    ((LocationMarker) this.mLocationMarkers.get(i)).anchorNode.setParent(this.mArSceneView.getScene());
                    ((LocationMarker) this.mLocationMarkers.get(i)).anchorNode.addChild(((LocationMarker) this.mLocationMarkers.get(i)).node);
                    if (((LocationMarker) this.mLocationMarkers.get(i)).getRenderEvent() != null) {
                        ((LocationMarker) this.mLocationMarkers.get(i)).anchorNode.setRenderEvent(((LocationMarker) this.mLocationMarkers.get(i)).getRenderEvent());
                    }

                    ((LocationMarker) this.mLocationMarkers.get(i)).anchorNode.setScaleModifier(((LocationMarker) this.mLocationMarkers.get(i)).getScaleModifier());
                    ((LocationMarker) this.mLocationMarkers.get(i)).anchorNode.setScaleAtDistance(((LocationMarker) this.mLocationMarkers.get(i)).shouldScaleAtDistance());
                    ((LocationMarker) this.mLocationMarkers.get(i)).anchorNode.setHeight(((LocationMarker) this.mLocationMarkers.get(i)).getHeight());

我替换了锚点创建中的代码,该行是旧代码 frame.getCamera().getPose()换成新的 frame.getCamera().getDisplayOrientedPose()

通过使用我在发布的问题to create renderables中创建上述工作代码的链接以及演示示例here,我正在发布所需的链接。

0 个答案:

没有答案