Пример #1
0
        private void FrameSelection(bool allKeys)
        {
            // Get min max value of all curves and keys.
            Vector2 min = new Vector2(Single.MaxValue, Single.MaxValue);
            Vector2 max = new Vector2(Single.MinValue, Single.MinValue);

            bool needToDefault = true;

            foreach (EditCurve curve in curves)
            {
                if (!allKeys && curve.Visible == false)
                {
                    continue;
                }

                for (int idx = 0; idx < curve.Keys.Count; ++idx)
                {
                    EditCurveKey key = curve.Keys[idx];

                    if (!allKeys && key.Selection == EditCurveSelections.None)
                    {
                        continue;
                    }

                    Vector2 pos = new Vector2(key.Position, key.Value);
                    min = Vector2.Min(min, pos);
                    max = Vector2.Max(max, pos);

                    // Sample few point for more aculate result.
                    if (idx < curve.Keys.Count - 1)
                    {
                        float nextPosition = curve.Keys[idx + 1].Position;

                        const int sampleCount = 4;
                        // at 0 is already sampled and 1 will be sampled in next loop.
                        float dt = 1.0f / (float)(sampleCount + 2);
                        float nt = dt;
                        for (int i = 0; i < sampleCount; ++i, nt += dt)
                        {
                            float t = MathHelper.Lerp(key.Position, nextPosition, nt);
                            pos = new Vector2(t, curve.Evaluate(t));
                            min = Vector2.Min(min, pos);
                            max = Vector2.Max(max, pos);
                        }
                    }
                    needToDefault = false;
                }
            }

            if (needToDefault)
            {
                min = -Vector2.One;
                max = Vector2.One;
            }

            if (curveView.Frame(min, max))
            {
                RequestRender();
            }
        }
Пример #2
0
 /// <summary>
 /// Mark modified key.
 /// </summary>
 private void MarkModify(EditCurveKey key)
 {
     // Clone and save current EditCurveKey to modified keys.
     if (modifiedKeys != null && !modifiedKeys.ContainsKey(key.Id))
     {
         modifiedKeys.Add(key.Id, key.Clone());
         dirty = true;
     }
 }
Пример #3
0
        public EditCurveKeyAddRemoveCommand(EditCurve curve, EditCurveKey addKey,
                                            EditCurveKeySelection selection)
        {
            this.curve     = curve;
            this.addKey    = true;
            this.selection = selection.Clone();

            keys = new List <EditCurveKey>();
            keys.Add(addKey.Clone());
        }
Пример #4
0
        /// <summary>
        /// Returns selected key list.
        /// </summary>
        /// <returns></returns>
        public EditCurveKey[] GetSelectedKeys()
        {
            EditCurveKey[] keys = new EditCurveKey[selectedKeys.Count];
            int            idx  = 0;

            foreach (EditCurveKey key in selectedKeys.Values)
            {
                keys[idx++] = key;
            }

            return(keys);
        }
Пример #5
0
        private void AddKeys()
        {
            foreach (EditCurveKey savedKey in keys)
            {
                EditCurveKey addingKey = savedKey.Clone();

                curve.Keys.Add(addingKey);

                // Removing key requires re-compute neighbor keys tangents.
                curve.ComputeTangents(curve.Keys.IndexOf(addingKey));
            }
            curve.ApplySelection(new EditCurveKeySelection(keys), false);
        }
Пример #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="key"></param>
        /// <param name="continuity"></param>
        private void SetKeyContinuity(EditCurveKey key, CurveContinuity continuity)
        {
            if (key.Continuity != continuity)
            {
                MarkModify(key);

                key.Continuity = continuity;
                if (continuity == CurveContinuity.Step)
                {
                    key.TangentIn     = key.TangentOut = 0;
                    key.TangentInType = key.TangentInType = EditCurveTangent.Flat;
                }
            }
        }
Пример #7
0
        private void DrawTangents(Graphics g, EditCurve curve)
        {
            System.Drawing.Color[] colors = new System.Drawing.Color[] { System.Drawing.Color.Yellow, System.Drawing.Color.Brown };
            float   len = 50.0f;
            Vector2 pt1 = new Vector2();

            EditCurveSelections tangentSelection = EditCurveSelections.Key |
                                                   EditCurveSelections.TangentIn |
                                                   EditCurveSelections.TangentOut;

            for (int i = 0; i < curve.Keys.Count; ++i)
            {
                EditCurveKey editKey = curve.Keys[i];
                CurveKey     key     = editKey.OriginalKey;

                EditCurveSelections selection = editKey.Selection;
                bool isSelecting = (selection & tangentSelection) != 0;

                if (((isSelecting && curve.Editable) ||
                     curveTangentsViewMode == EditCurveView.Always) &&
                    key.Continuity == CurveContinuity.Smooth)
                {
                    pt1 = curveView.ToPixelCoordinate(key.Position, key.Value);

                    int   colIdx = 0;
                    float screen_tangent;

                    // tan-in.
                    colIdx         = (selection & EditCurveSelections.TangentIn) != 0 ? 0 : 1;
                    screen_tangent = curveView.UnitToScreenTangentAngle(
                        key.TangentIn / curve.GetDistanceOfKeys(i, 0));

                    DrawArrow(g, pt1,
                              (float)Math.PI + (float)Math.Atan(screen_tangent),
                              len, colors[colIdx]);

                    // tan-out.
                    colIdx         = (selection & EditCurveSelections.TangentOut) != 0 ? 0 : 1;
                    screen_tangent = curveView.UnitToScreenTangentAngle(
                        key.TangentOut / curve.GetDistanceOfKeys(i, 1));

                    DrawArrow(g, pt1, (float)Math.Atan(screen_tangent), len,
                              colors[colIdx]);
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Compute specfied index key tangents.
        /// </summary>
        /// <param name="idx"></param>
        public void ComputeTangents(int keyIndex)
        {
            if (keyIndex < 0 || keyIndex > keys.Count || keyIndex > Int32.MaxValue - 2)
            {
                throw new ArgumentOutOfRangeException("keyIndex");
            }

            // Compute neighbors tangents too.
            for (int i = keyIndex - 1; i < keyIndex + 2; ++i)
            {
                if (i >= 0 && i < keys.Count)
                {
                    EditCurveKey key = keys[i];

                    MarkModify(key);

                    float        tangentInValue  = key.TangentIn;
                    float        tangentOutValue = key.TangentOut;
                    CurveTangent tangentIn       = Convert(key.TangentInType);
                    CurveTangent tangentOut      = Convert(key.TangentOutType);

                    OriginalCurve.ComputeTangent(i, tangentIn, tangentOut);

                    if (Single.IsNaN(key.TangentIn))
                    {
                        key.TangentIn = 0.0f;
                    }
                    if (Single.IsNaN(key.TangentOut))
                    {
                        key.TangentOut = 0.0f;
                    }

                    // Restore original value if EditCurveTanget is fixed.
                    if (key.TangentInType == EditCurveTangent.Fixed)
                    {
                        key.TangentIn = tangentInValue;
                    }

                    if (key.TangentOutType == EditCurveTangent.Fixed)
                    {
                        key.TangentOut = tangentOutValue;
                    }
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Apply given key values.
        /// </summary>
        /// <param name="newKeyValues"></param>
        public void ApplyKeyValues(ICollection <EditCurveKey> newKeyValues)
        {
            foreach (EditCurveKey newKeyValue in newKeyValues)
            {
                EditCurveKey key = newKeyValue.Clone();
                // Update key value.
                keys.Remove(keys.GetValue(key.Id));
                keys.Add(key);

                // Also, update key values if that key is selected.
                if (selectedKeys.ContainsKey(key.Id))
                {
                    selectedKeys.Remove(key.Id);
                    selectedKeys.Add(key.Id, key);
                }

                dirty = true;
            }
        }
Пример #10
0
        /// <summary>
        /// Add new key at given position.
        /// </summary>
        /// <param name="pos"></param>
        public void AddKey(Vector2 pos)
        {
            EnsureUpdating("AddKey");

            // Create new key.
            EditCurveKey key = new EditCurveKey(EditCurveKey.GenerateUniqueId(),
                                                new CurveKey(pos.X, pos.Y));

            key.Selection = EditCurveSelections.Key;

            // Generate add key command and execute it.
            EditCurveKeyAddRemoveCommand command =
                new EditCurveKeyAddRemoveCommand(this, key, selection);

            command.Execute();
            if (commandHistory != null)
            {
                commandHistory.Add(command);
            }
        }
Пример #11
0
        /// <summary>
        /// Apply key selection.
        /// </summary>
        /// <param name="newSelection"></param>
        /// <param name="generateCommand"></param>
        public void ApplySelection(EditCurveKeySelection newSelection,
                                   bool generateCommand)
        {
            // Re-create selected keys and store selection information from
            // new selection.
            selectedKeys.Clear();;
            foreach (long id in newSelection.Keys)
            {
                EditCurveKey key = keys.GetValue(id);
                key.Selection = newSelection[id];
                selectedKeys.Add(key.Id, key);
            }

            // Clear de-selected keys selection information.
            foreach (long id in selection.Keys)
            {
                if (!newSelection.ContainsKey(id))
                {
                    EditCurveKey key;
                    if (keys.TryGetValue(id, out key))
                    {
                        key.Selection = EditCurveSelections.None;
                    }
                }
            }

            // Invoke selection change event.
            if (generateCommand == true && !newSelection.Equals(selection) &&
                commandHistory != null)
            {
                commandHistory.Add(new SelectCommand(this, newSelection, selection));
            }

            // Update selection.
            selection = newSelection;
        }
Пример #12
0
        /// <summary>
        /// Draw actual part of curve.
        /// </summary>
        /// <param name="g"></param>
        /// <param name="pen"></param>
        /// <param name="curve"></param>
        /// <param name="t0"></param>
        /// <param name="t1"></param>
        /// <param name="step"></param>
        private void DrawCurve(Graphics g, Pen pen, EditCurve curve,
                               double t0, double t1, double step)
        {
            Vector2[] p = new Vector2[2] {
                new Vector2(), new Vector2()
            };

            // Search key and next key that includes t0 position.
            int          keyIndex = 0;
            EditCurveKey key = null, nextKey = null;

            for (; keyIndex < curve.Keys.Count; ++keyIndex)
            {
                key = nextKey; nextKey = curve.Keys[keyIndex];
                if (nextKey.Position > t0)
                {
                    break;
                }
            }

            int pIdx = 0;

            p[pIdx] = curveView.ToPixelCoordinate((float)t0, curve.Evaluate((float)t0));
            for (double t = t0; t < t1;)
            {
                double nextT = t1 + step;
                if (nextKey != null)
                {
                    nextT = Math.Min(t1, nextKey.Position);
                }

                // Draw current key and next key section.
                if (key.Continuity == CurveContinuity.Smooth)
                {
                    while (t < nextT)
                    {
                        // If this line crosses next key position, draw line from
                        // current position to next key position.
                        t       = (t <nextT && t + step> nextT)? nextT: t + step;
                        pIdx    = (pIdx + 1) & 1;
                        p[pIdx] = curveView.ToPixelCoordinate(
                            (float)t, curve.Evaluate((float)t));
                        DrawLine(g, pen, p[0], p[1]);
                    }
                }
                else
                {
                    // Step case,
                    // Draw, horizontal line.
                    pIdx    = (pIdx + 1) & 1;
                    p[pIdx] = curveView.ToPixelCoordinate(nextKey.Position, key.Value);
                    DrawLine(g, pen, p[0], p[1]);

                    // Draw vertical line.
                    pIdx    = (pIdx + 1) & 1;
                    p[pIdx] = curveView.ToPixelCoordinate(
                        nextKey.Position, nextKey.Value);
                    DrawLine(g, pen, p[0], p[1]);

                    t = nextT;
                }

                // Advance to next key.
                key     = nextKey;
                nextKey = (++keyIndex < curve.Keys.Count) ? curve.Keys[keyIndex] : null;
            }
        }