/// <summary> /// Sets the PCF to bind to and the transform to refer to when the PCF updates. /// Adds this binding to the passed PCF. /// </summary> public bool Bind(MLPersistentCoordinateFrames.PCF pcf, Transform transform, bool regain = false) { bool success = true; if (pcf != null) { this.pcf = pcf; } if (transform != null) { this.transform = transform; } if (regain) { success &= Regain(); } success &= Update(); if (success) { pcf.AddBinding(this); MLPersistentCoordinateFrames.QueueForUpdates(pcf); } return(success); }
private void HandlePCFPoseRetrieval(MLPersistentCoordinateFrames.PCF pcf) { //save results: _localPCFData.Add(pcf); //do we have all of them? if (_localPCFData.Count == _localPCFs.Count) { //sort by distance: _localPCFData = _localPCFData.OrderBy(p => Vector3.Distance(_mainCamera.position, p.Position)).ToList(); //grab a chunk of results: for (int i = 0; i < Mathf.Min(OutboundCount, _localPCFData.Count); i++) { //find offsets: _transformHelper.SetPositionAndRotation(_localPCFData[i].Position, _localPCFData[i].Rotation); Vector3 positionOffset = _transformHelper.InverseTransformPoint(Vector3.zero); Quaternion rotationOffset = Quaternion.Inverse(_transformHelper.rotation) * Quaternion.LookRotation(Vector3.forward); //catalog: _outboundPCFs.Add(new PCFMessage(_localPCFData[i].CFUID.ToString(), new Pose(positionOffset, rotationOffset), _interval)); _localPCFReferences.Add(_localPCFData[i].CFUID.ToString(), _localPCFData[i]); } //send them out: StartCoroutine("SendPCFs"); } }
private static string MakePCFString(MLPersistentCoordinateFrames.PCF pcf) { return($"ID: {pcf.CFUID.ToString()}\n" + $"position: {pcf.Position}\n" + $"rotation: {pcf.Rotation}\n" + $"confidence: {pcf.Confidence}\n" + $"rotation error: {pcf.RotationErrDeg} degrees\n" + $"translation error: {pcf.TranslationErrM} meters\n" + $"valid radius: {pcf.ValidRadiusM} meters\n" + $"type: {pcf.Type}"); }
//Coroutines: private IEnumerator WeAreTheOldest() { //make sure we found our anchor pcf: while (_anchorPCF == null) { yield return(null); } //update the global shared pcf: _sharedPCF = _anchorPCF; Reorient(); Transmission.SetGlobalString(_sharedPCFKey, _anchorPCF.CFUID.ToString()); }
/// <summary> /// Sets the PCF to bind to and the text mesh to refer to when the PCF updates. /// Adds this binding to the passed PCF. /// </summary> public void Bind(MLPersistentCoordinateFrames.PCF pcf, TextMesh textMesh) { if (pcf != null) { PCF = pcf; } if (textMesh != null) { _textMesh = textMesh; } if (PCF != null && _textMesh != null) { _textMesh = textMesh; PCF = pcf; PCF.AddBinding(this); MLPersistentCoordinateFrames.QueueForUpdates(pcf); switch (PCF.CurrentStatus) { case MLPersistentCoordinateFrames.PCF.Status.Created: { _textMesh.text = "<color=green>Created</color>\n" + GetPCFStateString(); break; } case MLPersistentCoordinateFrames.PCF.Status.Updated: { Update(); break; } case MLPersistentCoordinateFrames.PCF.Status.Regained: { Regain(); break; } case MLPersistentCoordinateFrames.PCF.Status.Lost: { Lost(); break; } } } }
private void OnStatusChange(MLPersistentCoordinateFrames.PCF.Status pcfStatus, MLPersistentCoordinateFrames.PCF pcf) { if (displayDebugVisuals) { if (pcfStatus == MLPersistentCoordinateFrames.PCF.Status.Created) { PCFAnchorVisual newVisual = Instantiate(AnchorVisualPrefab, pcf.Position, pcf.Rotation); newVisual.transform.parent = visualParent.transform; newVisual.GetComponent <PCFAnchorVisual>().PCF = pcf; } if (pcfStatus == MLPersistentCoordinateFrames.PCF.Status.Lost) { foreach (var visual in visualParent.GetComponentsInChildren <PCFAnchorVisual>()) { if (visual.PCF.Equals(pcf)) { DestroyImmediate(visual.gameObject); } } } if (pcfStatus == MLPersistentCoordinateFrames.PCF.Status.Updated) { foreach (var visual in visualParent.GetComponentsInChildren <PCFAnchorVisual>()) { if (visual.PCF.Equals(pcf)) { visual.gameObject.transform.position = pcf.Position; visual.gameObject.transform.rotation = pcf.Rotation; Debug.LogFormat("PCF Updated anchor: was {0}, is now {1}", visual.PCF.ToString(), pcf.ToString()); visual.PCF = pcf; } } } } }
private void HandlePCFStatusChange(MLPersistentCoordinateFrames.PCF.Status pcfStatus, MLPersistentCoordinateFrames.PCF pcf) { if (_sharedPCF != null && pcf.CFUID == _sharedPCF.CFUID) { //our shared pcf updated: Reorient(); } }
// // The status of the PCF subsystem and all PCFs for the localized map // private void onStatusChange(MLPersistentCoordinateFrames.PCF.Status pcfStatus, MLPersistentCoordinateFrames.PCF pcf) { // Retain our status so we can change the color of the cube if (pcf.CFUID == this.coordinateFrameUID) { this.status = pcfStatus; } /// /// Comment out the code below to print out the status for information purposes /// There is no need to adjust the position or rotation of the GameObject, since the /// TransformBinding will automatically adjust that for us. /// //switch (pcfStatus) //{ // case MLPersistentCoordinateFrames.PCF.Status.Lost: // print("MLPersistentCoordinateFrames.PCF.Status.Lost"); // break; // case MLPersistentCoordinateFrames.PCF.Status.Created: // print("MLPersistentCoordinateFrames.PCF.Status.Created"); // break; // case MLPersistentCoordinateFrames.PCF.Status.Updated: // print("MLPersistentCoordinateFrames.PCF.Status.Updated"); // break; // case MLPersistentCoordinateFrames.PCF.Status.Regained: // print("MLPersistentCoordinateFrames.PCF.Status.Regained"); // break; // case MLPersistentCoordinateFrames.PCF.Status.Stable: // { // print("MLPersistentCoordinateFrames.PCF.Status.Stable"); // } // break; // default: // print("MLPersistentCoordinateFrames status unknown"); // break; //} }
private ActsAsGlobalOrigin.AnchorResult anchorToClosestPCF(ActsAsGlobalOrigin.AnchorAttempt anchorAttempt, MLPersistentCoordinateFrames.PCF.Types type) { if (MLPersistentCoordinateFrames.IsLocalized == false) { print("Localized map must first be created before finding a PCF"); return(ActsAsGlobalOrigin.AnchorResult.GeneralFail); } MLResult resultFindClosestSecondaryPCFType = MLPersistentCoordinateFrames.FindClosestPCF(transform.position, out MLPersistentCoordinateFrames.PCF closestPCF, type); switch (resultFindClosestSecondaryPCFType.Result) { case MLResult.Code.Ok: { if (closestPCF == null) { return(resultFailFrom(anchorAttempt)); } else { /// /// Bind this GameObject's transform to the PCF /// this.transformBinding = new TransformBinding(this.GetInstanceID().ToString(), "ActsAsGlobalOrigin"); if (this.transformBinding == null) { return(resultFailFrom(anchorAttempt)); } if (this.transformBinding.Bind(closestPCF, transform)) { closestPCF.AddBinding(this); this.pcf = closestPCF; print("Added Binding"); return(resultSuccessFrom(anchorAttempt)); } else { return(resultFailFrom(anchorAttempt)); } } } case MLResult.Code.InvalidParam: throw new System.NotImplementedException(); case MLResult.Code.PrivilegeDenied: throw new System.NotImplementedException(); case MLResult.Code.UnspecifiedFailure: print("UnspecifiedFailure"); return(ActsAsGlobalOrigin.AnchorResult.GeneralFail); case MLResult.Code.PassableWorldLowMapQuality: print("PassableWorldLowMapQuality - quality of the room map is too low, re-map room"); return(ActsAsGlobalOrigin.AnchorResult.PassableWorldLowMapQuality); case MLResult.Code.PassableWorldUnableToLocalize: print("PassableWorldUnableToLocalize - room layout has changed, re-map room or adjust lighting"); return(ActsAsGlobalOrigin.AnchorResult.PassableWorldUnableToLocalize); } return(ActsAsGlobalOrigin.AnchorResult.GeneralFail); }
private bool locateAndReBindToPCFAnchor() { bool result = false; /// /// Iterate the persisted bindings that are stored locally on the device /// TransformBinding.storage.LoadFromFile(); List <TransformBinding> storedBindings = TransformBinding.storage.Bindings; List <TransformBinding> staleBindings = new List <TransformBinding>(); foreach (TransformBinding storedBinding in storedBindings) { /// /// Get the Coordinate Frame Unique Identifier /// this.coordinateFrameUID = storedBinding.PCF.CFUID; /// /// Find the PCF (Persistent Coordinate Frame) aka "The Anchor" /// MLPersistentCoordinateFrames.FindPCFByCFUID(coordinateFrameUID, out MLPersistentCoordinateFrames.PCF pcf); /// Gets the MLResult from the last query for the PCF's pose. It could be one of the following: /// <c>MLResult.Code.Pending</c> - /// <c>MLResult.Code.Ok</c> - Position/Orientation is reliable. /// Otherwise - Position/Orientation is unreliable. switch (pcf.CurrentResultCode) { case MLResult.Code.Pending: // Position/Orientation does not exist. staleBindings.Add(storedBinding); break; case MLResult.Code.Ok: // Position/Orientation is reliable, but pcf may be null { if (pcf == null) { staleBindings.Add(storedBinding); continue; } else { print("Found stored PCF -- Rebinding"); this.transformBinding = storedBinding; this.transformBinding.Bind(pcf, this.transform, true); this.pcf = pcf; result = true; } } break; default: // Position/Orientation is unreliable. { staleBindings.Add(storedBinding); continue; } } } foreach (TransformBinding staleBinding in staleBindings) { staleBinding.UnBind(); } if (!result) { print("Failed to locate stored binding."); } return(result); }
/// <summary> /// Handler for PCF status changes. /// </summary> /// <param name="pcfStatus">The PCF status.</param> /// <param name="pcf">The PCF.</param> private void HandlePCFStatusChange(MLPersistentCoordinateFrames.PCF.Status pcfStatus, MLPersistentCoordinateFrames.PCF pcf) { switch (pcfStatus) { // Creates a new gameobject to represent the newly created pcf. case MLPersistentCoordinateFrames.PCF.Status.Created: { #if PLATFORM_LUMIN GameObject pcfVisual = Instantiate(pcfVisualPrefab, pcf.Position, pcf.Rotation, transform); _pcfVisuals.Add(pcfVisual); pcfVisual.SetActive(IsVisualizing); #endif break; } } }
//Event Handlers: private void HandlePCFChanged(MLPersistentCoordinateFrames.PCF.Status pcfStatus, MLPersistentCoordinateFrames.PCF pcf) { if (pcfAnchor != null && pcf.CFUID == pcfAnchor.CFUID) { //adjust to pcf: pcfAnchor.Update(); AnchorToPCF(); FireOnUpdated(); } }