LocationMarkers рендеринг проблема в камере, а также не работает ViewRenderables в режиме альбомной камеры при вращении камеры - PullRequest
0 голосов
/ 06 июня 2019

Я работаю в библиотеке ARCore Google. В этом мне нужно поместить реальные маркеры местоположений в камере, поэтому я использую класс LocationMarker и другие классы LocationScene библиотеки ARCore, а также создаю 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);

}

а также я поместил пользовательские изменения класса LocationScene после того, как результат locationMarker становится правильным

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().

Я публикую необходимые ссылки, используя те, которые я создал вышеупомянутым рабочим кодом с опубликованной проблемой, для создания доступных для воспроизведения , а также используя демонстрационный пример здесь .

...