/// <summary> /// Disable tracking of Point of Interest. Destroys 3D-model and canvas objects. /// </summary> /// <param name="poi"></param> private void StopTrackingPOI(pLab_PointOfInterest poi) { poi.TrackingState = POITrackingState.NotTracking; POITrackerData trackerData = poiTrackerDatas.Find((x) => x.POI == poi); if (trackerData == null) { return; } pLab_PointOfInterestObjectBase poiObject = trackerData.POIObject; //Destroy and remove poi 3D-model if (poiObject != null) { Destroy(poiObject.gameObject); } //Destroy and remove poi canvas pLab_PointOfInterestCanvasBase poiCanvas = trackerData.POICanvas; if (poiCanvas != null) { Destroy(poiCanvas.gameObject); } poiTrackerDatas.Remove(trackerData); }
/// <summary> /// Stops tracking all the POIs, deleting all the canvases and gameobjects. /// </summary> private void StopTrackingPOIs() { if (poiTrackerDatas != null) { for (int i = 0; i < poiTrackerDatas.Count; i++) { POITrackerData trackerData = poiTrackerDatas[i]; if (trackerData == null) { continue; } pLab_PointOfInterest poi = trackerData.POI; if (poi != null) { poi.TrackingState = POITrackingState.NotTracking; } pLab_PointOfInterestObjectBase poiObject = trackerData.POIObject; //Destroy and remove poi 3D-model if (poiObject != null) { Destroy(poiObject.gameObject); } //Destroy and remove poi canvas pLab_PointOfInterestCanvasBase poiCanvas = trackerData.POICanvas; if (poiCanvas != null) { Destroy(poiCanvas.gameObject); } } //Make sure every poi is set to "NotTracking"-state for (int i = 0; i < PointOfInterests.Count; i++) { PointOfInterests[i].TrackingState = POITrackingState.NotTracking; } poiTrackerDatas.Clear(); } }
public POITrackerData(pLab_PointOfInterest poi, pLab_PointOfInterestCanvasBase poiCanvas) { this.poi = poi; this.poiCanvas = poiCanvas; }
public POITrackerData(pLab_PointOfInterest poi, pLab_PointOfInterestCanvasBase poiCanvas, pLab_PointOfInterestObjectBase poiObject) { this.poi = poi; this.poiCanvas = poiCanvas; this.poiObject = poiObject; }
/// <summary> /// Enable tracking for Point of Interest. Create 3D-model and canvas objects. /// </summary> /// <param name="poi"></param> private void CreateObjectsForPOI(pLab_PointOfInterest poi) { //Check if there is already objects for this tracker if (poiTrackerDatas != null && poiTrackerDatas.Count > 0) { POITrackerData poiTracker = poiTrackerDatas.Find((x) => x.POI == poi); if (poiTracker != null) { return; } } GameObject objectGo = null; GameObject modelGo = null; GameObject poiCanvasGo = null; pLab_PointOfInterestObjectBase poiObject = null; pLab_PointOfInterestCanvasBase poiCanvas = null; if (poi.ModelPrefab != null) { if (poi.ObjectPrefab == null) { objectGo = new GameObject($"Object tracker for {poi.PoiName}"); objectGo.transform.SetParent(poiParentObject); } else { objectGo = Instantiate(poi.ObjectPrefab, Vector3.zero, Quaternion.identity, poiParentObject); } modelGo = Instantiate(poi.ModelPrefab, Vector3.zero, Quaternion.identity, objectGo.transform); poiObject = objectGo.GetComponent <pLab_PointOfInterestObjectBase>(); if (poiObject == null) { poiObject = objectGo.AddComponent <pLab_PointOfInterestObject>(); } poiObject.Setup(poi, arCamera); poiObject.UpdateRotation(0); } if (poi.CanvasPrefab != null) { poiCanvasGo = Instantiate(poi.CanvasPrefab, Vector3.zero, Quaternion.identity, poiParentObject); poiCanvas = poiCanvasGo.GetComponent <pLab_PointOfInterestCanvasBase>(); if (poiCanvas == null) { poiCanvas = poiCanvasGo.AddComponent <pLab_PointOfInterestCanvas>(); } poiCanvas.Setup(poi, arCamera); } POITrackerData trackerData = new POITrackerData(poi, poiCanvas, poiObject); poiTrackerDatas.Add(trackerData); }
/// <summary> /// Move all tracked POI-objects /// </summary> private void RecheckPOITrackings() { pLab_LatLon currentLocation = locationProvider.Location; if (currentLocation == null) { return; } Vector3 currentARCameraPosition = arCameraTransform.position; float devicePosY = currentARCameraPosition.y; currentARCameraPosition.y = 0; float groundLevel = deviceElevationEstimater != null ? deviceElevationEstimater.GroundLevelEstimate : 0f; if (PointOfInterests == null || PointOfInterests.Count == 0) { return; } for (int i = 0; i < PointOfInterests.Count; i++) { pLab_PointOfInterest poi = PointOfInterests[i]; //Calculate the distance between the points float distanceBetween = currentLocation.DistanceToPointPythagoras(poi.Coordinates); bool onlyUpdateHeight = false; //Don't update the position if already so close //Maybe should actually search for a plane close to this and "anchor" it to that, or try to find nearest plane to get the height //If close tracking -> don't update the position to avoid jitter and unability to inspect object closely if (!poi.CloseTracking && distanceBetween <= poi.CloseTrackingRadius) { if (!poi.FarTracking) { CreateObjectsForPOI(poi); } poi.TrackingState = POITrackingState.CloseTracking; } else if (!poi.Tracking && distanceBetween <= poi.TrackingRadius) { poi.TrackingState = POITrackingState.FarTracking; CreateObjectsForPOI(poi); } else if (poi.Tracking && distanceBetween >= poi.TrackingExitRadius) { StopTrackingPOI(poi); } else if (poi.CloseTracking) { if (distanceBetween >= poi.CloseTrackingExitRadius) { poi.TrackingState = POITrackingState.FarTracking; } else { //Close Tracking is true AND poi is inside the closeTrackingRadius onlyUpdateHeight = true; } } POITrackerData trackerData = poiTrackerDatas.Find(x => x.POI == poi); if (trackerData == null) { continue; } float trueNorthHeadingDifference = arTrueNorthFinder != null ? arTrueNorthFinder.Heading : 0; pLab_PointOfInterestCanvasBase poiCanvas = trackerData.POICanvas; pLab_PointOfInterestObjectBase poiObject = trackerData.POIObject; //If we only update the height, set the heights and continue to the next POI if (onlyUpdateHeight) { if (poiObject != null) { poiObject.UpdatePositionY(groundLevel, devicePosY); } //Update poi's canvas position if (poiCanvas != null) { poiCanvas.UpdatePositionY(groundLevel, devicePosY); } continue; } Vector3 newPos = Vector3.zero; float bearing = 0; switch (positioningMode) { case PositioningMode.DistanceAndBearing: //Get the bearing relative to north (this is why it's important for the z-axis to face north) bearing = pLab_GeoTools.BearingFromPointAToB(currentLocation, poi.Coordinates); /** * Usually it should be X = cos(bearing), Y = sin(bearing) but for some reason it has to flipped other way around * So X = sin(bearing) and Z = cos(bearing) */ newPos = new Vector3(distanceBetween * Mathf.Sin(bearing), 0, distanceBetween * Mathf.Cos(bearing)); break; case PositioningMode.UTM: Vector2 UTMDifference = pLab_GeoTools.UTMDifferenceBetweenPoints(currentLocation, poi.Coordinates); newPos = new Vector3(UTMDifference.x, 0, UTMDifference.y); //For debugging bearing = Vector3.SignedAngle(Vector3.forward, newPos.normalized, Vector3.up); bearing = pLab_MathConversions.DegAngle0To360(bearing); bearing = pLab_MathConversions.DegToRad(bearing); //END debug distanceBetween = newPos.magnitude; break; } //Offset new position with current camera position trackerData.LastUpdateCameraPosition = currentARCameraPosition; trackerData.LastUpdatePositionRelativeToCamera = newPos; //Offset with true north difference so Z-axis == AR True-North-Axis newPos = currentARCameraPosition + (Quaternion.AngleAxis(trueNorthHeadingDifference, Vector3.up) * newPos); if (poiObject != null) { poiObject.UpdatePosition(newPos, groundLevel, devicePosY); poiObject.UpdateRotation(trueNorthHeadingDifference); } //Update poi's canvas position if (poiCanvas != null) { poiCanvas.UpdatePosition(newPos, groundLevel, devicePosY); poiCanvas.UpdateDistance(distanceBetween); } if (updateDebug) { pointOfInterestDebug.UpdateItem(poi, distanceBetween, bearing, newPos); } } updateDebug = false; }