Beispiel #1
0
        /// Pass a Canvas parent, and a transform in that canvas's space.
        /// If overrideDesc passed, use that for the visuals -- m_CurrentBrush does not change.
        public void CreateNewLine(CanvasScript canvas, TrTransform xf_CS,
                                  ParametricStrokeCreator creator, BrushDescriptor overrideDesc = null)
        {
            // If straightedge is enabled, we may have a minimum size requirement.
            // Initialize parametric stroke creator for our type of straightedge.
            // Maybe change the brush to a proxy brush.
            BrushDescriptor desc = overrideDesc != null ? overrideDesc : m_CurrentBrush;

            m_CurrentCreator = creator;

            // Parametric creators want control over the brush size.
            if (m_CurrentCreator != null)
            {
                m_ParametricCreatorBackupStrokeSize = m_CurrentBrushSize;
                m_CurrentBrushSize = m_CurrentCreator.ProcessBrushSize(m_CurrentBrushSize);
            }

            m_LastUsedBrushSize_CS = (1 / Coords.CanvasPose.scale) * BrushSizeAbsolute;
            m_LineLength_CS        = 0.0f;

            float jitteredBrushSize = m_CurrentBrushSize;

            if (PointerManager.m_Instance.JitterEnabled)
            {
                jitteredBrushSize = PointerManager.m_Instance.GenerateJitteredSize(desc, m_CurrentBrushSize);
            }

            m_CurrentLine = BaseBrushScript.Create(
                canvas.transform, xf_CS,
                desc, m_CurrentColor, jitteredBrushSize);
        }
Beispiel #2
0
        // Only called during interactive creation.
        // isContinue is true if the line is the logical (if not physical) continuation
        // of a previous line -- ie, previous line ran out of verts and we transparently
        // stopped and started a new one.
        void InitiateLine(bool isContinue = false)
        {
            // Turn off the preview when we start drawing
            for (int i = 0; i < m_NumActivePointers; ++i)
            {
                m_Pointers[i].m_Script.DisablePreviewLine();
                m_Pointers[i].m_Script.AllowPreviewLine(false);
            }

            if (m_StraightEdgeEnabled)
            {
                // This causes the line to be drawn with a proxy brush; and also to be
                // discarded and redrawn upon completion.
                m_StraightEdgeProxyActive = MainPointer.CurrentBrush.NeedsStraightEdgeProxy;
                // Turn on the straight edge and hold on to our start position
                m_StraightEdgeGuide.ShowGuide(MainPointer.transform.position);
                for (int i = 0; i < m_NumActivePointers; ++i)
                {
                    m_Pointers[i].m_StraightEdgeXf_CS = Coords.AsCanvas[m_Pointers[i].m_Script.transform];
                }
            }

            CanvasScript canvas = App.Scene.ActiveCanvas;

            for (int i = 0; i < m_NumActivePointers; ++i)
            {
                PointerScript script       = m_Pointers[i].m_Script;
                var           xfPointer_CS = canvas.AsCanvas[script.transform];

                // Pass in parametric stroke creator.
                ParametricStrokeCreator currentCreator = null;
                if (m_StraightEdgeEnabled)
                {
                    switch (StraightEdgeGuide.CurrentShape)
                    {
                    case StraightEdgeGuideScript.Shape.Line:
                        currentCreator = new LineCreator(xfPointer_CS, flat: true);
                        break;

                    case StraightEdgeGuideScript.Shape.Circle:
                        currentCreator = new CircleCreator(xfPointer_CS);
                        break;

                    case StraightEdgeGuideScript.Shape.Sphere:
                        currentCreator = new SphereCreator(xfPointer_CS, script.BrushSizeAbsolute,
                                                           canvas.transform.GetUniformScale());
                        break;
                    }
                }

                script.CreateNewLine(
                    canvas, xfPointer_CS, currentCreator,
                    m_StraightEdgeProxyActive ? m_StraightEdgeProxyBrush : null);
                script.SetControlPoint(xfPointer_CS, isKeeper: true);
            }
        }
Beispiel #3
0
        // During playback, rMemoryObjectForPlayback is non-null, and strokeFlags should not be passed.
        // otherwise, rMemoryObjectForPlayback is null, and strokeFlags should be valid.
        // When non-null, rMemoryObjectForPlayback corresponds to the current line.
        public void DetachLine(
            bool bDiscard,
            Stroke rMemoryObjectForPlayback,
            SketchMemoryScript.StrokeFlags strokeFlags = SketchMemoryScript.StrokeFlags.None)
        {
            if (rMemoryObjectForPlayback != null)
            {
                Debug.Assert(strokeFlags == SketchMemoryScript.StrokeFlags.None);
            }

            if (bDiscard)
            {
                m_CurrentLine.DestroyMesh();
                Destroy(m_CurrentLine.gameObject);
            }
            else if (App.Config.m_UseBatchedBrushes && m_CurrentLine.m_bCanBatch)
            {
                // Save line: batched case

                // ClearRedo() is called by MemorizeXxx(), but also do it earlier as a
                // fragmentation optimization; this allows GenerateBatchSubset() to reuse the
                // reclaimed space.
                // NB: batching currently handles fragmentation poorly, so consider this
                // optimization necessary.
                if (rMemoryObjectForPlayback == null)
                {
                    SketchMemoryScript.m_Instance.ClearRedo();
                }

                var subset = m_CurrentLine.FinalizeBatchedBrush();
                if (rMemoryObjectForPlayback == null)
                {
                    SketchMemoryScript.m_Instance.MemorizeBatchedBrushStroke(
                        subset, m_CurrentColor,
                        m_CurrentBrush.m_Guid,
                        m_CurrentBrushSize,
                        m_CurrentLine.StrokeScale,
                        m_ControlPoints, strokeFlags,
                        WidgetManager.m_Instance.ActiveStencil, m_LineLength_CS, m_CurrentLine.RandomSeed);
                }
                else
                {
                    //if we're in playback, patch up the in-memory stroke with its position in the batch
                    rMemoryObjectForPlayback.m_Type        = Stroke.Type.BatchedBrushStroke;
                    rMemoryObjectForPlayback.m_Object      = null;
                    rMemoryObjectForPlayback.m_BatchSubset = subset;
                    subset.m_Stroke = rMemoryObjectForPlayback;
                }

                //destroy original stroke, as it's now part of the batch stroke
                m_CurrentLine.DestroyMesh();
                Destroy(m_CurrentLine.gameObject);

                // recreate the stroke if it's just been drawn by the user, so we can run the simplifier on it.
                if (!App.Instance.IsLoading() &&
                    QualityControls.m_Instance.UserStrokeSimplifier.Level > 0.0f &&
                    m_CurrentLine.Descriptor.m_SupportsSimplification)
                {
                    var stroke = subset.m_Stroke;
                    stroke.InvalidateCopy();
                    stroke.Uncreate();
                    stroke.Recreate();
                }
            }
            else
            {
                // Save line: non-batched case

                if (rMemoryObjectForPlayback == null)
                {
                    SketchMemoryScript.m_Instance.MemorizeBrushStroke(
                        m_CurrentLine, m_CurrentColor,
                        m_CurrentBrush.m_Guid,
                        m_CurrentBrushSize,
                        m_CurrentLine.StrokeScale,
                        m_ControlPoints, strokeFlags,
                        WidgetManager.m_Instance.ActiveStencil, m_LineLength_CS);
                }
                else
                {
                    rMemoryObjectForPlayback.m_Type        = Stroke.Type.BrushStroke;
                    rMemoryObjectForPlayback.m_BatchSubset = null;
                    m_CurrentLine.Stroke = rMemoryObjectForPlayback;
                }

                //copy master brush over to current line
                m_CurrentLine.FinalizeSolitaryBrush();
            }

            if (rMemoryObjectForPlayback == null)
            {
                SilenceAudio();
            }

            m_CurrentLine = null;
            // Restore brush size if our parametric creator had to modify it.
            if (m_CurrentCreator != null)
            {
                m_CurrentBrushSize = m_ParametricCreatorBackupStrokeSize;
            }
            m_CurrentCreator = null;
            m_ControlPoints.Clear();
        }
Beispiel #4
0
        // During playback, rMemoryObjectForPlayback is non-null, and strokeFlags should not be passed.
        // otherwise, rMemoryObjectForPlayback is null, and strokeFlags should be valid.
        // When non-null, rMemoryObjectForPlayback corresponds to the current line.
        public void DetachLine(
            bool bDiscard,
            Stroke rMemoryObjectForPlayback,
            SketchMemoryScript.StrokeFlags strokeFlags = SketchMemoryScript.StrokeFlags.None)
        {
            if (ApiManager.Instance.HasOutgoingListeners)
            {
                var color           = App.BrushColor.CurrentColor;
                var pointsAsStrings = new List <string>();
                foreach (var cp in m_ControlPoints)
                {
                    var pos = cp.m_Pos;
                    var rot = cp.m_Orient.eulerAngles;
                    pointsAsStrings.Add($"[{pos.x},{pos.y},{pos.z},{rot.x},{rot.y},{rot.z},{cp.m_Pressure}]");
                }
                ApiManager.Instance.EnqueueOutgoingCommands(
                    new List <KeyValuePair <string, string> >
                {
                    new KeyValuePair <string, string>("brush.type", CurrentBrush.m_Guid.ToString()),
                    new KeyValuePair <string, string>("color.set.rgb", $"{color.r},{color.g},{color.b}"),
                    new KeyValuePair <string, string>("draw.stroke", string.Join(",", pointsAsStrings))
                }
                    );
            }

            if (rMemoryObjectForPlayback != null)
            {
                Debug.Assert(strokeFlags == SketchMemoryScript.StrokeFlags.None);
            }

            if (bDiscard)
            {
                m_CurrentLine.DestroyMesh();
                Destroy(m_CurrentLine.gameObject);
            }
            else if (App.Config.m_UseBatchedBrushes && m_CurrentLine.m_bCanBatch)
            {
                // Save line: batched case

                // ClearRedo() is called by MemorizeXxx(), but also do it earlier as a
                // fragmentation optimization; this allows GenerateBatchSubset() to reuse the
                // reclaimed space.
                // NB: batching currently handles fragmentation poorly, so consider this
                // optimization necessary.
                if (rMemoryObjectForPlayback == null)
                {
                    SketchMemoryScript.m_Instance.ClearRedo();
                }

                var subset = m_CurrentLine.FinalizeBatchedBrush();
                if (rMemoryObjectForPlayback == null)
                {
                    SketchMemoryScript.m_Instance.MemorizeBatchedBrushStroke(
                        subset, m_CurrentColor,
                        m_CurrentBrush.m_Guid,
                        m_CurrentBrushSize,
                        m_CurrentLine.StrokeScale,
                        m_ControlPoints, strokeFlags,
                        WidgetManager.m_Instance.ActiveStencil, m_LineLength_CS, m_CurrentLine.RandomSeed);
                }
                else
                {
                    //if we're in playback, patch up the in-memory stroke with its position in the batch
                    rMemoryObjectForPlayback.m_Type        = Stroke.Type.BatchedBrushStroke;
                    rMemoryObjectForPlayback.m_Object      = null;
                    rMemoryObjectForPlayback.m_BatchSubset = subset;
                    subset.m_Stroke = rMemoryObjectForPlayback;
                }

                //destroy original stroke, as it's now part of the batch stroke
                m_CurrentLine.DestroyMesh();
                Destroy(m_CurrentLine.gameObject);

                // recreate the stroke if it's just been drawn by the user, so we can run the simplifier on it.
                if (!App.Instance.IsLoading() &&
                    QualityControls.m_Instance.UserStrokeSimplifier.Level > 0.0f &&
                    m_CurrentLine.Descriptor.m_SupportsSimplification)
                {
                    var stroke = subset.m_Stroke;
                    stroke.InvalidateCopy();
                    stroke.Uncreate();
                    stroke.Recreate();
                }
            }
            else
            {
                // Save line: non-batched case

                if (rMemoryObjectForPlayback == null)
                {
                    SketchMemoryScript.m_Instance.MemorizeBrushStroke(
                        m_CurrentLine, m_CurrentColor,
                        m_CurrentBrush.m_Guid,
                        m_CurrentBrushSize,
                        m_CurrentLine.StrokeScale,
                        m_ControlPoints, strokeFlags,
                        WidgetManager.m_Instance.ActiveStencil, m_LineLength_CS);
                }
                else
                {
                    rMemoryObjectForPlayback.m_Type        = Stroke.Type.BrushStroke;
                    rMemoryObjectForPlayback.m_BatchSubset = null;
                    m_CurrentLine.Stroke = rMemoryObjectForPlayback;
                }

                //copy master brush over to current line
                m_CurrentLine.FinalizeSolitaryBrush();
            }

            if (rMemoryObjectForPlayback == null)
            {
                SilenceAudio();
            }

            m_CurrentLine = null;
            // Restore brush size if our parametric creator had to modify it.
            if (m_CurrentCreator != null)
            {
                m_CurrentBrushSize = m_ParametricCreatorBackupStrokeSize;
            }
            m_CurrentCreator = null;
            m_ControlPoints.Clear();
        }