diff --git a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARBeaconLayer.kt b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARBeaconLayer.kt index 56a42a169..27e674d9f 100644 --- a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARBeaconLayer.kt +++ b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARBeaconLayer.kt @@ -7,6 +7,7 @@ import com.kylecorry.andromeda.core.units.PixelCoordinate import com.kylecorry.sol.units.Distance import com.kylecorry.trail_sense.navigation.beacons.domain.Beacon import com.kylecorry.trail_sense.navigation.ui.DrawerBitmapLoader +import com.kylecorry.trail_sense.tools.augmented_reality.position.GeographicARPoint import kotlin.math.hypot // TODO: Figure out what to pass for the visible distance: d = 1.2246 * sqrt(h) where d is miles and h is feet (or move it to the consumer) @@ -93,37 +94,41 @@ class ARBeaconLayer( // TODO: Avoid recreating markers every time - it will help if this didn't filter nearby beacons // if (!areBeaconsUpToDate) { // TODO: Change opacity if navigating - layer.setMarkers(visible.flatMap { - val beacon = it.first - listOfNotNull( - ARMarkerImpl.geographic( + layer.setMarkers(visible.flatMap { + val beacon = it.first + listOfNotNull( + ARMarker( + GeographicARPoint( beacon.coordinate, beacon.elevation, beaconSize.distance, - CircleCanvasObject(beacon.color, Color.WHITE), - onFocusedFn = { - onFocus(beacon) - }, - onClickFn = { - onClick(beacon) - } ), - beacon.icon?.let { icon -> - val color = Colors.mostContrastingColor(Color.WHITE, Color.BLACK, beacon.color) - ARMarkerImpl.geographic( + CircleCanvasObject(beacon.color, Color.WHITE), + onFocusedFn = { + onFocus(beacon) + }, + onClickFn = { + onClick(beacon) + } + ), + beacon.icon?.let { icon -> + val color = Colors.mostContrastingColor(Color.WHITE, Color.BLACK, beacon.color) + ARMarker( + GeographicARPoint( beacon.coordinate, beacon.elevation, - beaconSize.distance, - BitmapCanvasObject( - loader.load(icon.icon, loadedImageSize), - 0.75f, - tint = color - ), - keepFacingUp = true - ) - } - ) - }) + beaconSize.distance + ), + BitmapCanvasObject( + loader.load(icon.icon, loadedImageSize), + 0.75f, + tint = color + ), + keepFacingUp = true + ) + } + ) + }) // areBeaconsUpToDate = true // } diff --git a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARLineLayer.kt b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARLineLayer.kt index f52bfa3cb..ca1ab6d02 100644 --- a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARLineLayer.kt +++ b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARLineLayer.kt @@ -7,7 +7,7 @@ import com.kylecorry.andromeda.canvas.ICanvasDrawer import com.kylecorry.andromeda.core.units.PixelCoordinate import com.kylecorry.sol.math.SolMath import com.kylecorry.sol.math.SolMath.normalizeAngle -import com.kylecorry.trail_sense.tools.augmented_reality.position.ARPositionStrategy +import com.kylecorry.trail_sense.tools.augmented_reality.position.ARPoint import kotlin.math.hypot import kotlin.math.min import kotlin.math.roundToInt @@ -20,10 +20,10 @@ class ARLineLayer( private val path = Path() - private val lines = mutableListOf>() + private val lines = mutableListOf>() private val lineLock = Any() - fun setLines(lines: List>) { + fun setLines(lines: List>) { synchronized(lineLock) { this.lines.clear() this.lines.addAll(lines) @@ -100,7 +100,7 @@ class ARLineLayer( */ private fun getLinePixels( view: AugmentedRealityView, - line: List, + line: List, resolutionDegrees: Float, maxDistance: Float, ): List> { diff --git a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARMarker.kt b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARMarker.kt index f3f738b30..e59fb93a2 100644 --- a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARMarker.kt +++ b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARMarker.kt @@ -1,11 +1,49 @@ package com.kylecorry.trail_sense.tools.augmented_reality import com.kylecorry.andromeda.canvas.ICanvasDrawer +import com.kylecorry.sol.units.Coordinate import com.kylecorry.trail_sense.shared.canvas.PixelCircle -import com.kylecorry.trail_sense.tools.augmented_reality.position.ARPositionStrategy +import com.kylecorry.trail_sense.tools.augmented_reality.position.ARPoint +import com.kylecorry.trail_sense.tools.augmented_reality.position.GeographicARPoint +import com.kylecorry.trail_sense.tools.augmented_reality.position.SphericalARPoint -interface ARMarker: ARPositionStrategy { - fun draw(view: AugmentedRealityView, drawer: ICanvasDrawer, area: PixelCircle) - fun onFocused(): Boolean - fun onClick(): Boolean +class ARMarker( + private val point: ARPoint, + private val canvasObject: CanvasObject, + private val keepFacingUp: Boolean = false, + private val onFocusedFn: (() -> Boolean) = { false }, + private val onClickFn: () -> Boolean = { false } +) { + + fun draw(view: AugmentedRealityView, drawer: ICanvasDrawer, area: PixelCircle) { + drawer.push() + if (keepFacingUp) { + drawer.rotate(view.sideInclination, area.center.x, area.center.y) + } + canvasObject.draw(drawer, area) + drawer.pop() + } + + /** + * Gets the location of the marker on the screen + * @param view The AR view + * @return The location of the marker + */ + fun getViewLocation(view: AugmentedRealityView): PixelCircle { + val coordinates = point.getHorizonCoordinate(view) + val angularDiameter = point.getAngularDiameter(view) + val diameter = view.sizeToPixel(angularDiameter) + return PixelCircle( + view.toPixel(coordinates), + diameter / 2f + ) + } + + fun onFocused(): Boolean { + return onFocusedFn() + } + + fun onClick(): Boolean { + return onClickFn() + } } \ No newline at end of file diff --git a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARMarkerImpl.kt b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARMarkerImpl.kt deleted file mode 100644 index 604d12a2c..000000000 --- a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARMarkerImpl.kt +++ /dev/null @@ -1,96 +0,0 @@ -package com.kylecorry.trail_sense.tools.augmented_reality - -import com.kylecorry.andromeda.canvas.ICanvasDrawer -import com.kylecorry.sol.units.Coordinate -import com.kylecorry.trail_sense.shared.camera.AugmentedRealityUtils -import com.kylecorry.trail_sense.shared.canvas.PixelCircle -import com.kylecorry.trail_sense.tools.augmented_reality.position.ARPositionStrategy -import com.kylecorry.trail_sense.tools.augmented_reality.position.GeographicPositionStrategy -import com.kylecorry.trail_sense.tools.augmented_reality.position.SphericalPositionStrategy -import kotlin.math.hypot - -// TODO: Are the helper methods needed, or can the constructor be called directly? -class ARMarkerImpl private constructor( - private val positionStrategy: ARPositionStrategy, - private val canvasObject: CanvasObject, - private val keepFacingUp: Boolean = false, - private val onFocusedFn: (() -> Boolean) = { false }, - private val onClickFn: () -> Boolean = { false } -) : ARMarker { - - override fun draw(view: AugmentedRealityView, drawer: ICanvasDrawer, area: PixelCircle) { - drawer.push() - if (keepFacingUp) { - drawer.rotate(view.sideInclination, area.center.x, area.center.y) - } - canvasObject.draw(drawer, area) - drawer.pop() - } - - override fun getAngularDiameter(view: AugmentedRealityView): Float { - return positionStrategy.getAngularDiameter(view) - } - - override fun getHorizonCoordinate(view: AugmentedRealityView): AugmentedRealityView.HorizonCoordinate { - return positionStrategy.getHorizonCoordinate(view) - } - - - override fun onFocused(): Boolean { - return onFocusedFn() - } - - override fun onClick(): Boolean { - return onClickFn() - } - - companion object { - fun horizon( - bearing: Float, - elevation: Float, - distance: Float = Float.MAX_VALUE, - isTrueNorth: Boolean = true, - angularDiameter: Float = 12f, - canvasObject: CanvasObject, - keepFacingUp: Boolean = false, - onFocusedFn: (() -> Boolean) = { false }, - onClickFn: () -> Boolean = { false } - ): ARMarker { - return ARMarkerImpl( - SphericalPositionStrategy( - bearing, - elevation, - distance, - angularDiameter, - isTrueNorth - ), - canvasObject, - keepFacingUp, - onFocusedFn, - onClickFn - ) - } - - fun geographic( - location: Coordinate, - elevation: Float?, - actualDiameter: Float, - canvasObject: CanvasObject, - keepFacingUp: Boolean = false, - onFocusedFn: (() -> Boolean) = { false }, - onClickFn: () -> Boolean = { false } - ): ARMarker { - return ARMarkerImpl( - GeographicPositionStrategy( - location, - elevation, - actualDiameter - ), - canvasObject, - keepFacingUp, - onFocusedFn, - onClickFn - ) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARMarkerLayer.kt b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARMarkerLayer.kt index 6cd66184e..d4604d584 100644 --- a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARMarkerLayer.kt +++ b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/ARMarkerLayer.kt @@ -119,12 +119,9 @@ class ARMarkerLayer( minimumPixelSize: Float, maximumPixelSize: Float ): PixelCircle { - val coordinates = marker.getHorizonCoordinate(view) - val angularDiameter = marker.getAngularDiameter(view) - val diameter = view.sizeToPixel(angularDiameter) - return PixelCircle( - view.toPixel(coordinates), - diameter.coerceIn(minimumPixelSize, maximumPixelSize) / 2f + val circle = marker.getViewLocation(view) + return circle.copy( + radius = circle.radius.coerceIn(minimumPixelSize / 2f, maximumPixelSize / 2f) ) } diff --git a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/AugmentedRealityFragment.kt b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/AugmentedRealityFragment.kt index 500fe71f4..1f6d68569 100644 --- a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/AugmentedRealityFragment.kt +++ b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/AugmentedRealityFragment.kt @@ -37,7 +37,8 @@ import com.kylecorry.trail_sense.shared.permissions.alertNoCameraPermission import com.kylecorry.trail_sense.shared.permissions.requestCamera import com.kylecorry.trail_sense.shared.sensors.LocationSubsystem import com.kylecorry.andromeda.fragments.observeFlow -import com.kylecorry.trail_sense.tools.augmented_reality.position.GeographicPositionStrategy +import com.kylecorry.trail_sense.tools.augmented_reality.position.GeographicARPoint +import com.kylecorry.trail_sense.tools.augmented_reality.position.SphericalARPoint import kotlinx.coroutines.Dispatchers import java.time.Duration import java.time.LocalDate @@ -104,7 +105,7 @@ class AugmentedRealityFragment : BoundFragment( if (it == null) { binding.arView.clearGuide() } else { - binding.arView.guideTo(GeographicPositionStrategy(it.coordinate, it.elevation)) { + binding.arView.guideTo(GeographicARPoint(it.coordinate, it.elevation)) { // Do nothing when reached } } @@ -249,11 +250,13 @@ class AugmentedRealityFragment : BoundFragment( moonAfterPathObject } - ARMarkerImpl.horizon( - astro.getMoonAzimuth(location, it).value, - astro.getMoonAltitude(location, it), - isTrueNorth = true, - angularDiameter = 1f, + ARMarker( + SphericalARPoint( + astro.getMoonAzimuth(location, it).value, + astro.getMoonAltitude(location, it), + isTrueNorth = true, + angularDiameter = 1f + ), canvasObject = obj, onFocusedFn = { binding.arView.focusText = @@ -275,11 +278,13 @@ class AugmentedRealityFragment : BoundFragment( sunAfterPathObject } - ARMarkerImpl.horizon( - astro.getSunAzimuth(location, it).value, - astro.getSunAltitude(location, it), - isTrueNorth = true, - angularDiameter = 1f, + ARMarker( + SphericalARPoint( + astro.getSunAzimuth(location, it).value, + astro.getSunAltitude(location, it), + isTrueNorth = true, + angularDiameter = 1f + ), canvasObject = obj, onFocusedFn = { binding.arView.focusText = @@ -304,11 +309,13 @@ class AugmentedRealityFragment : BoundFragment( val moonImageSize = Resources.dp(requireContext(), 24f).toInt() val moonBitmap = moonIcon?.toBitmapOrNull(moonImageSize, moonImageSize) - val moon = ARMarkerImpl.horizon( - moonAzimuth, - moonAltitude, - isTrueNorth = true, - angularDiameter = 2f, + val moon = ARMarker( + SphericalARPoint( + moonAzimuth, + moonAltitude, + isTrueNorth = true, + angularDiameter = 2f + ), canvasObject = moonBitmap?.let { BitmapCanvasObject(moonBitmap) } ?: CircleCanvasObject(Color.WHITE), onFocusedFn = { @@ -318,11 +325,13 @@ class AugmentedRealityFragment : BoundFragment( } ) - val sun = ARMarkerImpl.horizon( - sunAzimuth, - sunAltitude, - isTrueNorth = true, - angularDiameter = 2f, + val sun = ARMarker( + SphericalARPoint( + sunAzimuth, + sunAltitude, + isTrueNorth = true, + angularDiameter = 2f + ), canvasObject = CircleCanvasObject(AppColor.Yellow.color), onFocusedFn = { binding.arView.focusText = getString(R.string.sun) diff --git a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/AugmentedRealityView.kt b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/AugmentedRealityView.kt index f73ce847f..a451bb381 100644 --- a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/AugmentedRealityView.kt +++ b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/AugmentedRealityView.kt @@ -27,7 +27,7 @@ import com.kylecorry.trail_sense.shared.declination.DeclinationUtils import com.kylecorry.trail_sense.shared.sensors.SensorService import com.kylecorry.trail_sense.shared.text import com.kylecorry.trail_sense.shared.textDimensions -import com.kylecorry.trail_sense.tools.augmented_reality.position.ARPositionStrategy +import com.kylecorry.trail_sense.tools.augmented_reality.position.ARPoint import java.time.Duration import kotlin.math.atan2 @@ -109,7 +109,7 @@ class AugmentedRealityView : CanvasView { private val layerLock = Any() // Guidance - private var guideStrategy: ARPositionStrategy? = null + private var guideStrategy: ARPoint? = null private var guideThreshold: Float? = null private var onGuideReached: (() -> Unit)? = null @@ -156,7 +156,7 @@ class AugmentedRealityView : CanvasView { } fun guideTo( - guideStrategy: ARPositionStrategy, + guideStrategy: ARPoint, thresholdDegrees: Float? = null, onReached: () -> Unit = { clearGuide() } ) { diff --git a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/ARPositionStrategy.kt b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/ARPoint.kt similarity index 59% rename from app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/ARPositionStrategy.kt rename to app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/ARPoint.kt index 6a536a25f..1daa00569 100644 --- a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/ARPositionStrategy.kt +++ b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/ARPoint.kt @@ -2,7 +2,17 @@ package com.kylecorry.trail_sense.tools.augmented_reality.position import com.kylecorry.trail_sense.tools.augmented_reality.AugmentedRealityView -interface ARPositionStrategy { +/** + * A point in the AR world + */ +interface ARPoint { + /** + * Gets the horizon (spherical) coordinate of the point + */ fun getHorizonCoordinate(view: AugmentedRealityView): AugmentedRealityView.HorizonCoordinate + + /** + * Gets the angular diameter of the point in degrees + */ fun getAngularDiameter(view: AugmentedRealityView): Float } \ No newline at end of file diff --git a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/GeographicPositionStrategy.kt b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/GeographicARPoint.kt similarity index 76% rename from app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/GeographicPositionStrategy.kt rename to app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/GeographicARPoint.kt index f282a9af9..9dc699192 100644 --- a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/GeographicPositionStrategy.kt +++ b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/GeographicARPoint.kt @@ -5,11 +5,17 @@ import com.kylecorry.trail_sense.shared.camera.AugmentedRealityUtils import com.kylecorry.trail_sense.tools.augmented_reality.AugmentedRealityView import kotlin.math.hypot -class GeographicPositionStrategy( +/** + * A point in the AR world + * @param location The location of the point + * @param elevation The elevation of the point in meters, defaults to the elevation of the camera + * @param actualDiameter The actual diameter of the point in meters, defaults to 1 meter + */ +class GeographicARPoint( private val location: Coordinate, private val elevation: Float? = null, private val actualDiameter: Float = 1f -) : ARPositionStrategy { +) : ARPoint { override fun getAngularDiameter(view: AugmentedRealityView): Float { val distance = hypot( view.location.distanceTo(location), diff --git a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/SphericalPositionStrategy.kt b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/SphericalARPoint.kt similarity index 57% rename from app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/SphericalPositionStrategy.kt rename to app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/SphericalARPoint.kt index a8e472b1d..7cf084de3 100644 --- a/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/SphericalPositionStrategy.kt +++ b/app/src/main/java/com/kylecorry/trail_sense/tools/augmented_reality/position/SphericalARPoint.kt @@ -2,15 +2,23 @@ package com.kylecorry.trail_sense.tools.augmented_reality.position import com.kylecorry.trail_sense.tools.augmented_reality.AugmentedRealityView -class SphericalPositionStrategy( +/** + * A point in spherical coordinates + * @param bearing The bearing in degrees + * @param elevationAngle The elevation angle in degrees + * @param distance The distance in meters, defaults to MAX_VALUE + * @param angularDiameter The angular diameter in degrees, defaults to 1 + * @param isTrueNorth True if the bearing is true north, false if it is magnetic north + */ +class SphericalARPoint( bearing: Float, - elevation: Float, + elevationAngle: Float, distance: Float = Float.MAX_VALUE, private val angularDiameter: Float = 1f, isTrueNorth: Boolean = true -) : ARPositionStrategy { +) : ARPoint { private val position = - AugmentedRealityView.HorizonCoordinate(bearing, elevation, distance, isTrueNorth) + AugmentedRealityView.HorizonCoordinate(bearing, elevationAngle, distance, isTrueNorth) override fun getAngularDiameter(view: AugmentedRealityView): Float { return angularDiameter diff --git a/app/src/main/java/com/kylecorry/trail_sense/tools/clinometer/ui/ClinometerFragment.kt b/app/src/main/java/com/kylecorry/trail_sense/tools/clinometer/ui/ClinometerFragment.kt index 5d5ec0413..a9e082509 100644 --- a/app/src/main/java/com/kylecorry/trail_sense/tools/clinometer/ui/ClinometerFragment.kt +++ b/app/src/main/java/com/kylecorry/trail_sense/tools/clinometer/ui/ClinometerFragment.kt @@ -42,12 +42,11 @@ import com.kylecorry.trail_sense.shared.permissions.alertNoCameraPermission import com.kylecorry.trail_sense.shared.permissions.requestCamera import com.kylecorry.trail_sense.shared.sensors.SensorService import com.kylecorry.trail_sense.tools.augmented_reality.ARLineLayer -import com.kylecorry.trail_sense.tools.augmented_reality.ARMarkerImpl +import com.kylecorry.trail_sense.tools.augmented_reality.ARMarker import com.kylecorry.trail_sense.tools.augmented_reality.ARMarkerLayer -import com.kylecorry.trail_sense.tools.augmented_reality.AugmentedRealityView import com.kylecorry.trail_sense.tools.augmented_reality.CircleCanvasObject -import com.kylecorry.trail_sense.tools.augmented_reality.position.ARPositionStrategy -import com.kylecorry.trail_sense.tools.augmented_reality.position.SphericalPositionStrategy +import com.kylecorry.trail_sense.tools.augmented_reality.position.ARPoint +import com.kylecorry.trail_sense.tools.augmented_reality.position.SphericalARPoint import kotlinx.coroutines.Dispatchers import java.time.Duration import java.time.Instant @@ -90,8 +89,8 @@ class ClinometerFragment : BoundFragment() { private val fovRunner = CoroutineQueueRunner(1, dispatcher = Dispatchers.Default) private val markerLayer = ARMarkerLayer() private val lineLayer = ARLineLayer() - private var startMarker: ARPositionStrategy? = null - private var endMarker: ARPositionStrategy? = null + private var startMarker: ARPoint? = null + private var endMarker: ARPoint? = null private val isAugmentedReality by lazy { prefs.isAugmentedRealityEnabled @@ -304,6 +303,8 @@ class ClinometerFragment : BoundFragment() { private fun clearStartAngle() { startIncline = 0f + lineLayer.clearLines() + markerLayer.clearMarkers() binding.cameraClinometer.startInclination = null binding.clinometer.startAngle = null } @@ -319,16 +320,20 @@ class ClinometerFragment : BoundFragment() { // Calculate the distance away using the hypotenuse of the triangle val adjacent = distanceAway?.meters()?.distance ?: 10f val hypotenuse = adjacent / cosDegrees(startIncline) - val start = ARMarkerImpl.horizon( + val startPoint = SphericalARPoint( binding.arView.azimuth, binding.arView.inclination, isTrueNorth = prefs.compass.useTrueNorth, distance = hypotenuse, - angularDiameter = 1f, - canvasObject = CircleCanvasObject(AppColor.Orange.color) + angularDiameter = 1f + ) + startMarker = startPoint + markerLayer.addMarker( + ARMarker( + startPoint, + CircleCanvasObject(AppColor.Orange.color) + ) ) - startMarker = start - markerLayer.addMarker(start) } private fun setEndAngle() { @@ -338,16 +343,20 @@ class ClinometerFragment : BoundFragment() { // Calculate the distance away using the hypotenuse of the triangle val adjacent = distanceAway?.meters()?.distance ?: 10f val hypotenuse = adjacent / cosDegrees(slopeIncline ?: 0f) - val end = ARMarkerImpl.horizon( + val endPoint = SphericalARPoint( binding.arView.azimuth, binding.arView.inclination, isTrueNorth = prefs.compass.useTrueNorth, distance = hypotenuse, - angularDiameter = 1f, - canvasObject = CircleCanvasObject(AppColor.Orange.color) + angularDiameter = 1f + ) + endMarker = endPoint + markerLayer.addMarker( + ARMarker( + endPoint, + CircleCanvasObject(AppColor.Orange.color) + ) ) - endMarker = end - markerLayer.addMarker(end) } private fun clearEndAngle() { @@ -355,6 +364,7 @@ class ClinometerFragment : BoundFragment() { slopeIncline = null startMarker = null endMarker = null + lineLayer.clearLines() markerLayer.clearMarkers() } @@ -475,12 +485,12 @@ class ClinometerFragment : BoundFragment() { updateCamera() - if (isAugmentedReality) { + if (isAugmentedReality && startMarker != null) { lineLayer.setLines( listOf( listOfNotNull( startMarker, - endMarker ?: SphericalPositionStrategy( + endMarker ?: SphericalARPoint( binding.arView.azimuth, binding.arView.inclination, isTrueNorth = prefs.compass.useTrueNorth,