/// <summary> /// Find all matching pairs of frozen and spongy visuals, and if appropriate, /// create edges connecting them. Destroy any other stale lines. /// </summary> /// <param name="displacementCreator">Object to manage creating, destroying, and deciding existence of displacement lines.</param> /// <param name="frozenResources">The frozen anchors.</param> /// <param name="spongyResources">The spongy anchors.</param> /// <param name="displacementResources">The connecting lines.</param> private void SyncDisplacements( DisplacementCreator displacementCreator, IReadOnlyList <IdPair <AnchorId, FrozenAnchorVisual> > frozenResources, IReadOnlyList <IdPair <AnchorId, SpongyAnchorVisual> > spongyResources, List <IdPair <AnchorId, ConnectingLine> > displacementResources) { int iFrozen = 0; int iDisplace = 0; for (int iSpongy = 0; iSpongy < spongyResources.Count; ++iSpongy) { while (iFrozen < frozenResources.Count && frozenResources[iFrozen].id < spongyResources[iSpongy].id) { iFrozen++; } /// If we've reached the end of the frozen resources, we're finished creating. if (iFrozen >= frozenResources.Count) { break; } if (displacementCreator.ShouldConnect(frozenResources[iFrozen], spongyResources[iSpongy])) { AnchorId id = frozenResources[iFrozen].id; Debug.Assert(id == spongyResources[iSpongy].id); while (iDisplace < displacementResources.Count && displacementResources[iDisplace].id < id) { displacementCreator.DestroyDisplacement(displacementResources[iDisplace]); displacementResources.RemoveAt(iDisplace); } Debug.Assert(iDisplace <= displacementResources.Count); Debug.Assert(iDisplace == displacementResources.Count || displacementResources[iDisplace].id >= id); if (iDisplace == displacementResources.Count || displacementResources[iDisplace].id > id) { displacementResources.Insert(iDisplace, displacementCreator.CreateDisplacement( id, frozenResources[iFrozen].target, spongyResources[iSpongy].target)); } ++iDisplace; } } // Finished creating. Now destroy any displacements further in the list, as they no longer have matching // frozen/spongy pairs. Debug.Assert(iDisplace <= displacementResources.Count); int displacementCount = iDisplace; while (iDisplace < displacementResources.Count) { displacementCreator.DestroyDisplacement(displacementResources[iDisplace++]); } displacementResources.RemoveRange(displacementCount, displacementResources.Count - displacementCount); Debug.Assert(displacementResources.Count == displacementCount); }
/// <summary> /// Update all frozen visualizations. /// </summary> private void UpdateFrozen() { Debug.Assert(manager != null, "This should not be called without a valid manager"); var plugin = manager.Plugin; AnchorFragmentPose[] frozenItems = plugin.GetFrozenAnchors(); Array.Sort(frozenItems, (x, y) => x.anchorId.CompareTo(y.anchorId)); UpdateFragmentVisuals(); /// The "frozen" coordinates here are ignoring the rest of the transform up the camera tree. Pose globalFromLocked = manager.ApplyAdjustment ? manager.FrozenFromLocked : manager.SpongyFromLocked; /// Apply the vertical displacement through the globalFromLocked transform. globalFromLocked.position = new Vector3(globalFromLocked.position.x, globalFromLocked.position.y + verticalDisplacement, globalFromLocked.position.z); var frozenCreator = new FrozenAnchorVisualCreator(Prefab_FrozenAnchorViz, frozenFragmentVizs, globalFromLocked); ResourceMirror.Sync( frozenItems, frozenResources, (item, res) => item.anchorId.CompareTo(res.id), frozenCreator.CreateFrozenVisual, frozenCreator.UpdateFrozenVisual, frozenCreator.DestroyFrozenVisual); // Connect frozen anchors with corresponding spongy anchors with a line. DisplacementCreator displacementCreator = new DisplacementCreator(); SyncDisplacements(displacementCreator, frozenResources, spongyResources, displacementResources); var edgeItems = plugin.GetFrozenEdges(); for (int i = 0; i < edgeItems.Length; ++i) { edgeItems[i] = RegularizeEdge(edgeItems[i]); } Array.Sort(edgeItems, anchorEdgeComparer); var frozenEdgeCreator = new FrozenEdgeVisualCreator(this, frozenResources); ResourceMirror.Sync( edgeItems, edgeResources, (x, y) => CompareAnchorEdges(x, y.id), frozenEdgeCreator.CreateFrozenEdge, (x, y) => { }, frozenEdgeCreator.DestroyFrozenEdge); }