Beispiel #1
0
        /// <summary>
        /// If conditions have changed to allow finalizing creation of any pending attachment points,
        /// do it now.
        /// </summary>
        private void ProcessPendingAttachmentPoints()
        {
            if (CurrentFragmentId.IsKnown() && pendingAttachments.Count > 0)
            {
                // We have a valid destination fragment. Note that since this queue is in order of submission,
                // if an attachment point depends on a second attachment point for context,
                // that second will be either earlier in the list (because there was no valid current fragment when it was
                // created) or it will have a valid fragment. So by the time we get to the one with a dependency (pending.context != null),
                // its dependency will have a valid fragment id.
                int pendingCount = pendingAttachments.Count;
                for (int i = 0; i < pendingCount; ++i)
                {
                    AttachmentPoint  target         = pendingAttachments[i].target;
                    Vector3          frozenPosition = pendingAttachments[i].target.ObjectPosition;
                    IAttachmentPoint context        = pendingAttachments[i].context;

                    SetupAttachmentPoint(plugin, target, context);

                    FragmentId fragmentId = CurrentFragmentId;
                    if (context != null)
                    {
                        fragmentId = context.FragmentId;
                    }
                    Debug.Assert(fragmentId.IsKnown(), $"FragmentId {fragmentId.FormatStr()} invalid from {(context != null ? "context" : "head")} in processing pending");
                    Fragment fragment = EnsureFragment(fragmentId);
                    Debug.Assert(fragment != null, "Valid fragmentId but no fragment found");
                    fragment.AddAttachmentPoint(target);
                }
                // All pending must now be in a good home fragment, clear the to-do list.
                pendingAttachments.Clear();
            }
        }
Beispiel #2
0
        /// <summary>
        /// Invoke a refreeze operation on the plugin, and make all necessary adjustments
        /// in bookeeping after.
        /// </summary>
        /// <returns>True for successful refreeze.</returns>
        public bool Refreeze()
        {
            FragmentId targetFragmentId;

            FragmentId[] absorbedIds;
            if (!plugin.Refreeze(out targetFragmentId, out absorbedIds))
            {
                return(false);
            }
            Debug.Assert(targetFragmentId.IsKnown(), "Received invalid merged fragment id from successful refreeze");

            Fragment targetFragment = EnsureFragment(targetFragmentId);

            Debug.Assert(targetFragment != null, "Valid fragmentId but no fragment found");

            for (int i = 0; i < absorbedIds.Length; ++i)
            {
                FragmentId sourceId = absorbedIds[i];
                if (sourceId != targetFragmentId)
                {
                    Fragment sourceFragment;
                    if (fragments.TryGetValue(sourceId, out sourceFragment))
                    {
                        targetFragment.AbsorbOtherFragment(sourceFragment);
                        fragments.Remove(sourceId);
                    }
                    else
                    {
                        Debug.LogError($"Try to merge in a non-existent fragment {sourceId.FormatStr()}");
                    }
                }
            }
            CurrentFragmentId = targetFragmentId;

            // now apply individual adjustments to each attachment point.
            targetFragment.AdjustAll(plugin);

            // now that all adjustments have been made, notify the plugin to finish up the operation.
            plugin.RefreezeFinish();

            refitNotifications?.Invoke(targetFragment.FragmentId, absorbedIds);

            return(true);
        }
Beispiel #3
0
        /// <summary>
        /// Call on the plugin to compute the merge, then apply by
        /// setting transforms and adjusting scene graph.
        /// </summary>
        /// <returns>True for successful merge.</returns>
        public bool Merge()
        {
            FragmentId targetFragmentId;

            FragmentPose[] mergeAdjustments;
            if (!plugin.Merge(out targetFragmentId, out mergeAdjustments))
            {
                return(false);
            }
            Debug.Assert(targetFragmentId.IsKnown(), "Received invalid merged fragment id from successful merge");

            Fragment targetFragment = EnsureFragment(targetFragmentId);

            Debug.Assert(targetFragment != null, "Valid fragmentId but null target fragment from Merge");

            int numAbsorbed = mergeAdjustments.Length;

            for (int i = 0; i < numAbsorbed; ++i)
            {
                FragmentId sourceId   = mergeAdjustments[i].fragmentId;
                Pose       adjustment = mergeAdjustments[i].pose;
                Fragment   sourceFragment;
                if (fragments.TryGetValue(sourceId, out sourceFragment))
                {
                    targetFragment.AbsorbOtherFragment(sourceFragment, adjustment);
                    fragments.Remove(sourceId);
                }
                else
                {
                    Debug.LogError($"Try to merge in a non-existent fragment {sourceId.FormatStr()}");
                }
            }
            CurrentFragmentId = targetFragmentId;

            ApplyActiveCurrentFragment();

            refitNotifications?.Invoke(targetFragment.FragmentId, ExtractFragmentIds(mergeAdjustments));

            return(true);
        }
        /// <summary>
        /// If still waiting for a valid current fragment since last load,
        /// and there is a current valid fragment, set it to reference poses.
        /// </summary>
        private void CheckFragment()
        {
            bool changed = ActiveFragmentId != CurrentFragmentId;

            if (needFragment && CurrentFragmentId.IsKnown())
            {
                FragmentId fragmentId = CurrentFragmentId;
                for (int i = 0; i < referencePoses.Count; ++i)
                {
                    if (!referencePoses[i].fragmentId.IsKnown())
                    {
                        DebugLogSaveLoad($"Transfer {referencePoses[i].anchorId.FormatStr()} from frag={referencePoses[i].fragmentId.FormatStr()} to {fragmentId.FormatStr()}");
                        referencePoses[i].fragmentId = fragmentId;
                        changed = true;
                    }
                }
                needFragment = false;
            }
            if (changed)
            {
                ActivateCurrentFragment();
            }
        }