// combine all marker tracking heuristics into one result static SimulatedMarkerTrackingResult GetMarsCameraTrackingQuality(SynthesizedMarker marker, Camera cam) { var markerTrans = marker.transform; var markerPos = markerTrans.position; var markerUp = markerTrans.up; // tolerance > 1 allows tracking loss to happen when most of the marker goes out, not just the center const float relaxedTolerance = 1.1f; // if the marker is outside the camera frustum, the device can't see/track it anymore if (!SimulatedTrackingUtils.PointInFrustum(cam, markerPos, relaxedTolerance)) { return(new SimulatedMarkerTrackingResult(0f, TrackingFailureCause.OutOfFrustum)); } var camTrans = cam.transform; var camPos = camTrans.position; var camForward = camTrans.forward; var distance = Vector3.Distance(camPos, markerPos); var distanceQuality = GetDistanceQuality(marker.Extents, distance); // markers that are too far away can't be tracked if (distanceQuality <= 0f) { return(new SimulatedMarkerTrackingResult(0f, TrackingFailureCause.OutOfRange)); } // assume marker isn't occluded by environment in the case where the physics scene is not available var occluded = false; var hitCount = 0; #if UNITY_EDITOR var simScene = EditorOnlyDelegates.GetSimulatedEnvironmentScene(); if (simScene.IsValid()) { var physicScene = simScene.GetPhysicsScene(); if (physicScene.IsValid()) { occluded = TestPointOcclusion(physicScene, camPos, markerPos, out hitCount); } } #endif if (occluded) { return(new SimulatedMarkerTrackingResult(0f, TrackingFailureCause.Occluded, k_RayHits[0].point, hitCount)); } var alignmentQuality = GetImageAlignmentQuality(markerUp, camForward); // this is important to consider in combination with the surface viewing angle test, // because the camera's forward can be aligned with the marker's normal without actually looking at the marker var lookDirQuality = GetLookDirectionQuality(markerPos, camPos, camForward); return(new SimulatedMarkerTrackingResult(alignmentQuality * lookDirQuality * distanceQuality)); }
void AddMarkerData(SynthesizedMarker synthMarker, ref MRMarker marker, MARSTrackingState trackingState) { var dataId = UpdateMarkerData(ref marker, trackingState); synthMarker.dataID = dataId; // add every trait that won't change in here - semantic tags and marker id in this case this.AddOrUpdateTrait(dataId, TraitNames.Marker, true); this.AddOrUpdateTrait(dataId, TraitNames.MarkerId, marker.markerId.ToString()); k_TempSynthTags.Clear(); synthMarker.GetComponents(k_TempSynthTags); foreach (var synthTag in k_TempSynthTags) { if (!synthTag.isActiveAndEnabled) { continue; } this.AddOrUpdateTrait(dataId, synthTag.TraitName, synthTag.GetTraitData()); } }
void UpdateTracking(SynthesizedMarker synthesizedMarker, Camera marsCamera) { if (!synthesizedMarker.isActiveAndEnabled) { return; } var marker = synthesizedMarker.GetData(); if (marker.id == MarsTrackableId.InvalidId) { return; } // synth markers always report 'Tracking', here we calculate the tracking state for the mars camera var trackingState = GetTrackingState(synthesizedMarker, marsCamera); var previouslyFound = m_DiscoveredTrackables.Contains(marker.id); var tracking = trackingState != MARSTrackingState.Unknown; // don't add any data to the database until the first time the camera sees the marker well enough to track. if (!previouslyFound) { if (!tracking) { return; } m_DiscoveredTrackables.Add(marker.id); AddMarkerData(synthesizedMarker, ref marker, trackingState); markerAdded?.Invoke(marker); } else { UpdateMarkerData(ref marker, trackingState); markerUpdated?.Invoke(marker); } }
static MARSTrackingState GetTrackingState(SynthesizedMarker marker, Camera marsCam) { var result = GetMarsCameraTrackingQuality(marker, marsCam); return(GetTrackingState(result.Quality)); }