Пример #1
0
 /// There is no reasonable way for a caller to know what to pass for "endCustomDimension",
 /// because moving or scaling the widget (with some change in endXf) may cause the widget's
 /// CustomDimension values to change, too.
 ///
 /// Typically, a caller will pass widget.CustomDimension and assume that this
 /// is the correct value. Or, callers will go through some custom API on the widget
 /// (see CubeStencil.RecordAndApplyScaleToAxis) which has knowledge of its own internals
 /// and can compute the proper endCustomDimension to pass.
 public MoveWidgetCommand(GrabWidget widget, TrTransform endXf, Vector3 endCustomDimension,
                          bool final = false, BaseCommand parent = null) : base(parent)
 {
     m_Widget         = widget;
     m_Final          = final;
     m_StartTransform = widget.LocalTransform;
     if (widget is StencilWidget)
     {
         m_Type = Type.Guide;
     }
     else if (widget is MediaWidget)
     {
         m_Type = Type.Media;
         m_StartTransform.scale = widget.GetSignedWidgetSize();
     }
     else if (widget is SymmetryWidget)
     {
         m_Type = Type.Symmetry;
     }
     else if (widget is SelectionWidget)
     {
         m_Type = Type.Selection;
         m_StartSelectionTransform = SelectionManager.m_Instance.SelectionTransform;
         m_EndSelectionTransform   = SelectionManager.m_Instance.SelectionTransform;
     }
     m_CustomDimension.startState = widget.CustomDimension;
     m_EndTransform             = endXf;
     m_CustomDimension.endState = endCustomDimension;
 }
Пример #2
0
            // ------------------------------------------------------------------------------------------ //
            // Private Internals
            // ------------------------------------------------------------------------------------------ //

            override protected void OnReadResults()
            {
                // Mark results as ready.
                m_ResultCount = 0;
                if (m_ResultList != null)
                {
                    m_ResultList.Clear();
                }

                uint[] resultColors = GetTextureColors();

                //
                // Process the color buffer into result objects, if requested.
                //
                UnityEngine.Profiling.Profiler.BeginSample("Intersection: Process Model Results");
                HashSet <object> seen = AllocateHashSet();
                uint             c;

                for (int i = 0; i < resultColors.Length; i++)
                {
                    if (m_ResultCount == m_MaxResults)
                    {
                        break;
                    }

                    c = resultColors[i];

                    if (c > 0)
                    {
                        // Don't bother looking up the batch if the exact result set wasn't requested.
                        if (m_ResultList == null)
                        {
                            m_ResultCount++;
                            continue;
                        }

                        ushort     batchId = (ushort)((c & 0xffff0000) >> 16);
                        GrabWidget widget  = WidgetManager.m_Instance.GetBatch(batchId);
                        if (widget == null)
                        {
                            continue;
                        }

                        if (!seen.Add(widget))
                        {
                            continue;
                        }

                        m_ResultList.Add(new ModelResult {
                            widget = widget
                        });
                        m_ResultCount++;
                    }
                }

                DeallocateHashSet(seen);
                UnityEngine.Profiling.Profiler.EndSample();
            }
Пример #3
0
 public void Init(Transform parent, GrabWidget parentWidget)
 {
     m_WorkingPenetrationScalar = m_PenetrationScalar;
     m_DestroyOnStateComplete   = false;
     m_WobbleCountdown          = 0.0f;
     m_Parent             = parent;
     m_ParentWidgetScript = parentWidget;
     InitTransformedSpawnOffset();
 }
Пример #4
0
        protected override void OnRedo()
        {
            if (m_Widget != null)
            {
                // If we're re-doing this command and the widget exists, it's because we had previously
                // undone a creation.  The widget will be hidden at this point, so we want to restore it,
                // much in the opposite way HideWidgetCommand works.
                // TODO: This function name is used more generally and should be renamed.
                m_Widget.gameObject.SetActive(true);
                m_Widget.RestoreFromToss();
            }
            else
            {
                m_Widget = Object.Instantiate(m_Prefab);
                m_Widget.transform.position = m_SpawnXf.translation;

                // Widget type specific initialization.
                if (m_Widget is StencilWidget)
                {
                    m_Widget.transform.parent = m_Canvas.transform;
                    m_Widget.Show(true);
                }
                else if (m_Widget is ModelWidget)
                {
                    // ModelWidget.Show(true) is not called here because the model must be assigned
                    // before it can be turned on.
                }
                else if (m_Widget is ImageWidget)
                {
                    m_Widget.transform.parent = m_Canvas.transform;
                    m_Widget.Show(true);
                }
                else if (m_Widget is VideoWidget)
                {
                    m_Widget.transform.parent = m_Canvas.transform;
                    m_Widget.Show(true);
                }
                else if (m_Widget is CameraPathWidget)
                {
                    m_Widget.transform.parent        = m_Canvas.transform;
                    m_Widget.transform.localPosition = Vector3.zero;
                    m_Widget.transform.localRotation = Quaternion.identity;
                    m_Widget.Show(true);
                    App.Switchboard.TriggerCameraPathCreated();
                    WidgetManager.m_Instance.CameraPathsVisible = true;
                }

                m_Widget.InitIntroAnim(m_SpawnXf, m_EndXf, false, m_DesiredEndForward);
                m_TiltMeterCost = m_Widget.GetTiltMeterCost();
            }

            WidgetManager.m_Instance.RefreshPinAndUnpinLists();
            TiltMeterScript.m_Instance.AdjustMeterWithWidget(m_TiltMeterCost, up: true);
            m_TiltMeterCostUndone = false;
        }
Пример #5
0
        private void AddToGroupToSelectedWidgets(SketchGroupTag group, GrabWidget widget)
        {
            if (!m_GroupToSelectedWidgets.TryGetValue(group, out var groupWidgets))
            {
                groupWidgets = m_GroupToSelectedWidgets[group] = new HashSet <GrabWidget>();
            }
            Debug.Assert(!groupWidgets.Contains(widget));
            groupWidgets.Add(widget);

            App.Switchboard.TriggerSelectionChanged();
        }
Пример #6
0
        private void RemoveFromGroupToSelectedWidgets(SketchGroupTag group, GrabWidget widget)
        {
            var groupWidgets = m_GroupToSelectedWidgets[group];

            groupWidgets.Remove(widget);
            if (groupWidgets.Count == 0)
            {
                m_GroupToSelectedWidgets.Remove(group);
            }

            App.Switchboard.TriggerSelectionChanged();
        }
Пример #7
0
        override protected bool HandleIntersectionWithWidget(GrabWidget widget)
        {
            if (widget.Pinned == m_InPinningMode)
            {
                return(false);
            }

            SketchMemoryScript.m_Instance.PerformAndRecordCommand(
                new PinWidgetCommand(widget, m_InPinningMode));
            m_LastIntersectionTime  = Time.realtimeSinceStartup;
            m_IntersectionThisFrame = true;

            // Pull/add from our cached list.
            WidgetManager.m_Instance.RefreshPinAndUnpinLists();
            return(true);
        }
Пример #8
0
 public HideWidgetCommand(GrabWidget widget, BaseCommand parent = null)
     : base(parent)
 {
     m_Widget = widget;
     if (widget is StencilWidget)
     {
         m_WidgetTransform = TrTransform.FromLocalTransform(widget.transform);
     }
     else if (widget is MediaWidget)
     {
         m_WidgetTransform       = TrTransform.FromLocalTransform(widget.transform);
         m_WidgetTransform.scale = widget.GetSignedWidgetSize();
     }
     m_TiltMeterCost = m_Widget.GetTiltMeterCost();
     TiltMeterScript.m_Instance.AdjustMeterWithWidget(m_TiltMeterCost, up: false);
 }
Пример #9
0
        public void OnWidgetRemovedFromGroup(GrabWidget widget, SketchGroupTag oldGroup)
        {
            // If the widget is in the selection, then we need to update our group to selected widget
            // mapping.
            if (m_SelectedWidgets.Contains(widget))
            {
                RemoveFromGroupToSelectedWidgets(oldGroup, widget);
            }

            // Remove the widget from the old group to widgets mapping.
            if (oldGroup != SketchGroupTag.None)
            {
                // Remove this widget from the dictionary entry for the old group.
                m_GroupToWidgets[oldGroup].Remove(widget);
            }
        }
Пример #10
0
        // Creates a new widget by instantiating the prefab and setting its transform.
        // spawnXf is in world space.
        public CreateWidgetCommand(
            GrabWidget widgetPrefab,
            TrTransform spawnXf,
            Quaternion?desiredEndForward = null,
            BaseCommand parent           = null)
            : base(parent)
        {
            Transform controller = InputManager.m_Instance.GetController(
                InputManager.ControllerName.Brush).transform;

            m_Canvas  = App.ActiveCanvas;
            m_SpawnXf = spawnXf;
            m_EndXf   = TrTransform.TRS(
                Vector3.Lerp(m_SpawnXf.translation, controller.position, m_SpawnAggression),
                controller.rotation,
                m_SpawnXf.scale);
            m_Prefab            = widgetPrefab;
            m_DesiredEndForward = desiredEndForward;
        }
Пример #11
0
        /// Select a group that a widget belongs to and then return the corresponding selection widget.
        public SelectionWidget StartGrabbingGroupWithWidget(GrabWidget grabWidget)
        {
            m_IsGrabbingGroup = true;

            // Save off the current tool and selection.
            m_ToolTypeBeforeGrabbingGroup           = SketchSurfacePanel.m_Instance.ActiveToolType;
            m_SelectedStrokesCopyWhileGrabbingGroup = new HashSet <Stroke>(m_SelectedStrokes);
            m_SelectedWidgetsCopyWhileGrabbingGroup = new HashSet <GrabWidget>(m_SelectedWidgets);

            // Select the group that the widget belongs to.
            ClearActiveSelection();
            SketchMemoryScript.m_Instance.PerformAndRecordCommand(
                new SelectCommand(null, new[] { grabWidget },
                                  SelectionTransform,
                                  deselect: false, initial: true, isGrabbingGroup: true));
            UpdateSelectionWidget();
            ResolveChanges();

            SketchSurfacePanel.m_Instance.ActiveTool.HideTool(true);
            return(m_SelectionWidget);
        }
Пример #12
0
        override protected bool HandleIntersectionWithWidget(GrabWidget widget)
        {
            // Can't select a pinned widget.
            if (widget.Pinned)
            {
                return(false);
            }

            var  isSelected          = SelectionManager.m_Instance.IsWidgetSelected(widget);
            bool removeFromSelection = SelectionManager.m_Instance.ShouldRemoveFromSelection();

            if ((removeFromSelection && !isSelected) || (!removeFromSelection && isSelected))
            {
                Debug.LogWarning(
                    "Attempted to " + (removeFromSelection ? "deselect" : "select") +
                    " a widget that's already " + (isSelected ? "selected" : "deselected") + ".");
                return(true);
            }

            PlayModifyStrokeSound();

            SketchMemoryScript.m_Instance.PerformAndRecordCommand(
                new SelectCommand(null,
                                  new[] { widget },
                                  SelectionManager.m_Instance.SelectionTransform,
                                  initial: !m_ActiveSelectionHasAtLeastOneObject,
                                  deselect: removeFromSelection));
            m_ActiveSelectionHasAtLeastOneObject = true;
            m_LastIntersectionTime = Time.realtimeSinceStartup;

            // If we're selecting something while an existing selection has been transformed,
            // create a new selection and consolidate the command for selecting the future strokes
            // with the command to deselect the prior selection.
            if (!removeFromSelection && SelectionManager.m_Instance.SelectionWasTransformed)
            {
                EndSelection();
            }

            return(true);
        }
Пример #13
0
        public void OnWidgetAddedToGroup(GrabWidget widget)
        {
            SketchGroupTag newGroup = widget.Group;

            // If the widget is in the selection, then we need to update our group to selected widget
            // mapping.
            if (m_SelectedWidgets.Contains(widget))
            {
                AddToGroupToSelectedWidgets(widget.Group, widget);
            }

            // Add the widget to the new group to widgets mapping.
            if (newGroup != SketchGroupTag.None)
            {
                // Add this widget to the dictionary entry for the new group.
                if (!m_GroupToWidgets.TryGetValue(newGroup, out var newGroupWidgets))
                {
                    newGroupWidgets = m_GroupToWidgets[newGroup] = new HashSet <GrabWidget>();
                }
                newGroupWidgets.Add(widget);
            }
        }
Пример #14
0
 override protected bool HandleIntersectionWithWidget(GrabWidget widget)
 {
     return(false);
 }
Пример #15
0
            // ------------------------------------------------------------------------------------------ //
            // Private Internals
            // ------------------------------------------------------------------------------------------ //

            override protected void OnReadResults()
            {
                // Mark results as ready.
                m_ResultCount = 0;
                if (m_ResultList != null)
                {
                    m_ResultList.Clear();
                }

                uint[] resultColors = GetTextureColors();

                //
                // Process the color buffer into result objects, if requested.
                //
                UnityEngine.Profiling.Profiler.BeginSample("Intersection: Process Results");
                HashSet <object> seen = AllocateHashSet();

                uint c;

                for (int i = 0; i < resultColors.Length; i++)
                {
                    if (m_ResultCount == m_MaxResults)
                    {
                        break;
                    }

                    c = resultColors[i];

                    if (c > 0)
                    {
                        // Don't bother looking up the batch if the exact result set wasn't requested.
                        if (m_ResultList == null)
                        {
                            m_ResultCount++;
                            continue;
                        }

                        // TODO: the Color32 -> object lookup is deterministic and O(n), so 'seen'
                        // should store the Color32, not the object.

                        int         triIndex = (int)(c & 0xffff) * 3;
                        ushort      batchId  = (ushort)((c & 0xffff0000) >> 16);
                        GrabWidget  widget   = null;
                        Batch       batch    = null;
                        BatchSubset subset   = null;

                        // See if this batch refers to a brush stroke.
                        batch = App.ActiveCanvas.BatchManager.GetBatch(batchId);
                        if (batch != null)
                        {
                            // TODO: move this into Batch, so can do binary search if necessary
                            for (int j = 0; j < batch.m_Groups.Count; j++)
                            {
                                BatchSubset bs = batch.m_Groups[j];
                                if (triIndex >= bs.m_iTriIndex && triIndex < bs.m_iTriIndex + bs.m_nTriIndex)
                                {
                                    subset = bs;
                                    break;
                                }
                            }

                            // A stroke may be deleted by the time this executes. This is due to the delay between
                            // sending an intersection request and processing the results.
                            if (subset == null)
                            {
                                // This actually happens in practice!
                                // TODO: investigate if it's okay
                                // Debug.LogWarningFormat(
                                //     "Unexpected: Nonexistent subset for c = {0:x} {1:x}",
                                //     (ushort)(c >> 16),
                                //     (ushort)(c & 0xffff));
                                continue;
                            }

                            if (!seen.Add(subset))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            // Not a brush stroke?  See if this is a widget.
                            widget = WidgetManager.m_Instance.GetBatch(batchId);

                            // A widget may be deleted by the time this executes. This is due to the delay between
                            // sending an intersection request and processing the results.
                            if (widget == null)
                            {
                                continue;
                            }

                            if (!seen.Add(widget))
                            {
                                continue;
                            }
                        }

                        // A batch should never be null, but in the future that may change. This is possible due
                        // to the delay between sending an intersection request and processing the results.
                        if (batch == null && widget == null)
                        {
                            Debug.LogWarningFormat(
                                "Unexpected: Null batch {0} and widget {1}",
                                ReferenceEquals(batch, null), ReferenceEquals(widget, null));
                            continue;
                        }

                        // These cannot both be valid.
                        Debug.Assert(subset == null || widget == null);
                        m_ResultList.Add(
                            new BatchResult {
                            widget = widget, subset = subset
                        });
                        m_ResultCount++;
                    }
                }

                DeallocateHashSet(seen);
                UnityEngine.Profiling.Profiler.EndSample();
            }
Пример #16
0
 public PinWidgetCommand(GrabWidget widget, bool pin, BaseCommand parent = null)
   : base(parent) {
   m_Widget = widget;
   m_Pinning = pin;
 }
Пример #17
0
 public bool IsWidgetSelected(GrabWidget widget)
 {
     return(m_SelectedWidgets.Contains(widget));
 }
Пример #18
0
 virtual protected bool HandleIntersectionWithWidget(GrabWidget widget)
 {
     return(true);
 }