Я работаю в библиотеке 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()
.
Я публикую необходимые ссылки, используя те, которые я создал вышеупомянутым рабочим кодом с опубликованной проблемой, для создания доступных для воспроизведения , а также используя демонстрационный пример здесь .