示例#1
0
        /// <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);
        }