public void SetCurveState(SerializedProperty curve, CurveState state)
        {
            if (!m_Curves.ContainsKey(curve))
                throw new KeyNotFoundException("curve");

            m_Curves[curve] = state;
        }
Exemple #2
0
 public void AddCurve(CurveState transition, double start, double end)
 {
     CurveTransition = transition;
     StartCurve      = start;
     EndCurve        = end;
     CurveStep       = (EndCurve - StartCurve) / _segmentCount;
 }
        public void SetCurveState(AnimationCurve curve, CurveState state)
        {
            if (!_mCurves.ContainsKey(curve))
            {
                throw new KeyNotFoundException("curve");
            }

            _mCurves[curve] = state;
        }
        public void Add(SerializedProperty curve, CurveState state)
        {
            // Make sure the property is in fact an AnimationCurve
            var animCurve = curve.animationCurveValue;
            if (animCurve == null)
                throw new ArgumentException("curve");

            if (m_Curves.ContainsKey(curve))
                Debug.LogWarning("Curve has already been added to the editor");

            m_Curves.Add(curve, state);
        }
Exemple #5
0
        public void Add(SerializedProperty curve, CurveState state)
        {
            // Make sure the property is in fact an AnimationCurve
            var animCurve = curve.animationCurveValue;
            if (animCurve == null)
                throw new ArgumentException("curve");

            if (m_Curves.ContainsKey(curve))
                Debug.LogWarning("Curve has already been added to the editor");

            m_Curves.Add(curve, state);
        }
Exemple #6
0
        void OnCurveGUI(Rect rect, SerializedProperty curve, CurveState state)
        {
            // Discard invisible curves
            if (!state.visible)
            {
                return;
            }

            var animCurve = curve.animationCurveValue;
            var keys      = animCurve.keys;
            var length    = keys.Length;

            // Curve drawing
            // Slightly dim non-editable curves
            var color = state.color;

            if (!state.editable)
            {
                color.a *= 0.5f;
            }

            Handles.color = color;
            var bounds = settings.bounds;

            if (length == 0)
            {
                var p1 = CurveToCanvas(new Vector3(bounds.xMin, state.zeroKeyConstantValue));
                var p2 = CurveToCanvas(new Vector3(bounds.xMax, state.zeroKeyConstantValue));
                Handles.DrawAAPolyLine(state.width, p1, p2);
            }
            else if (length == 1)
            {
                var p1 = CurveToCanvas(new Vector3(bounds.xMin, keys[0].value));
                var p2 = CurveToCanvas(new Vector3(bounds.xMax, keys[0].value));
                Handles.DrawAAPolyLine(state.width, p1, p2);
            }
            else
            {
                var prevKey = keys[0];
                for (int k = 1; k < length; k++)
                {
                    var key = keys[k];
                    var pts = BezierSegment(prevKey, key);

                    if (float.IsInfinity(prevKey.outTangent) || float.IsInfinity(key.inTangent))
                    {
                        var s = HardSegment(prevKey, key);
                        Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]);
                    }
                    else
                    {
                        Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width);
                    }

                    prevKey = key;
                }

                // Curve extents & loops
                if (keys[0].time > bounds.xMin)
                {
                    if (state.loopInBounds)
                    {
                        var p1 = keys[length - 1];
                        p1.time -= settings.bounds.width;
                        var p2  = keys[0];
                        var pts = BezierSegment(p1, p2);

                        if (float.IsInfinity(p1.outTangent) || float.IsInfinity(p2.inTangent))
                        {
                            var s = HardSegment(p1, p2);
                            Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]);
                        }
                        else
                        {
                            Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width);
                        }
                    }
                    else
                    {
                        var p1 = CurveToCanvas(new Vector3(bounds.xMin, keys[0].value));
                        var p2 = CurveToCanvas(keys[0]);
                        Handles.DrawAAPolyLine(state.width, p1, p2);
                    }
                }

                if (keys[length - 1].time < bounds.xMax)
                {
                    if (state.loopInBounds)
                    {
                        var p1 = keys[length - 1];
                        var p2 = keys[0];
                        p2.time += settings.bounds.width;
                        var pts = BezierSegment(p1, p2);

                        if (float.IsInfinity(p1.outTangent) || float.IsInfinity(p2.inTangent))
                        {
                            var s = HardSegment(p1, p2);
                            Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]);
                        }
                        else
                        {
                            Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width);
                        }
                    }
                    else
                    {
                        var p1 = CurveToCanvas(keys[length - 1]);
                        var p2 = CurveToCanvas(new Vector3(bounds.xMax, keys[length - 1].value));
                        Handles.DrawAAPolyLine(state.width, p1, p2);
                    }
                }
            }

            // Make sure selection is correct (undo can break it)
            bool isCurrentlySelectedCurve = curve == m_SelectedCurve;

            if (isCurrentlySelectedCurve && m_SelectedKeyframeIndex >= length)
            {
                m_SelectedKeyframeIndex = -1;
            }

            // Handles & keys
            for (int k = 0; k < length; k++)
            {
                bool isCurrentlySelectedKeyframe = k == m_SelectedKeyframeIndex;
                var  e = Event.current;

                var pos     = CurveToCanvas(keys[k]);
                var hitRect = new Rect(pos.x - 8f, pos.y - 8f, 16f, 16f);
                var offset  = isCurrentlySelectedCurve
                    ? new RectOffset(5, 5, 5, 5)
                    : new RectOffset(6, 6, 6, 6);

                var outTangent        = pos + CurveTangentToCanvas(keys[k].outTangent).normalized * 40f;
                var inTangent         = pos - CurveTangentToCanvas(keys[k].inTangent).normalized * 40f;
                var inTangentHitRect  = new Rect(inTangent.x - 7f, inTangent.y - 7f, 14f, 14f);
                var outTangentHitrect = new Rect(outTangent.x - 7f, outTangent.y - 7f, 14f, 14f);

                // Draw
                if (state.showNonEditableHandles)
                {
                    if (e.type == EventType.Repaint)
                    {
                        var selectedColor = (isCurrentlySelectedCurve && isCurrentlySelectedKeyframe)
                            ? settings.selectionColor
                            : state.color;

                        // Keyframe
                        EditorGUI.DrawRect(offset.Remove(hitRect), selectedColor);

                        // Tangents
                        if (isCurrentlySelectedCurve && (!state.onlyShowHandlesOnSelection || (state.onlyShowHandlesOnSelection && isCurrentlySelectedKeyframe)))
                        {
                            Handles.color = selectedColor;

                            if (k > 0 || state.loopInBounds)
                            {
                                Handles.DrawAAPolyLine(state.handleWidth, pos, inTangent);
                                EditorGUI.DrawRect(offset.Remove(inTangentHitRect), selectedColor);
                            }

                            if (k < length - 1 || state.loopInBounds)
                            {
                                Handles.DrawAAPolyLine(state.handleWidth, pos, outTangent);
                                EditorGUI.DrawRect(offset.Remove(outTangentHitrect), selectedColor);
                            }
                        }
                    }
                }

                // Events
                if (state.editable)
                {
                    // Keyframe move
                    if (m_EditMode == EditMode.Moving && e.type == EventType.MouseDrag && isCurrentlySelectedCurve && isCurrentlySelectedKeyframe)
                    {
                        EditMoveKeyframe(animCurve, keys, k);
                    }

                    // Tangent editing
                    if (m_EditMode == EditMode.TangentEdit && e.type == EventType.MouseDrag && isCurrentlySelectedCurve && isCurrentlySelectedKeyframe)
                    {
                        bool alreadyBroken = !(Mathf.Approximately(keys[k].inTangent, keys[k].outTangent) || (float.IsInfinity(keys[k].inTangent) && float.IsInfinity(keys[k].outTangent)));
                        EditMoveTangent(animCurve, keys, k, m_TangentEditMode, e.shift || !(alreadyBroken || e.control));
                    }

                    // Keyframe selection & context menu
                    if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition))
                    {
                        if (hitRect.Contains(e.mousePosition))
                        {
                            if (e.button == 0)
                            {
                                SelectKeyframe(curve, k);
                                m_EditMode = EditMode.Moving;
                                e.Use();
                            }
                            else if (e.button == 1)
                            {
                                // Keyframe context menu
                                var menu = new GenericMenu();
                                menu.AddItem(new GUIContent("Delete Key"), false, (x) =>
                                {
                                    var action     = (MenuAction)x;
                                    var curveValue = action.curve.animationCurveValue;
                                    action.curve.serializedObject.Update();
                                    RemoveKeyframe(curveValue, action.index);
                                    m_SelectedKeyframeIndex = -1;
                                    SaveCurve(action.curve, curveValue);
                                    action.curve.serializedObject.ApplyModifiedProperties();
                                }, new MenuAction(curve, k));
                                menu.ShowAsContext();
                                e.Use();
                            }
                        }
                    }

                    // Tangent selection & edit mode
                    if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition))
                    {
                        if (inTangentHitRect.Contains(e.mousePosition) && (k > 0 || state.loopInBounds))
                        {
                            SelectKeyframe(curve, k);
                            m_EditMode        = EditMode.TangentEdit;
                            m_TangentEditMode = Tangent.In;
                            e.Use();
                        }
                        else if (outTangentHitrect.Contains(e.mousePosition) && (k < length - 1 || state.loopInBounds))
                        {
                            SelectKeyframe(curve, k);
                            m_EditMode        = EditMode.TangentEdit;
                            m_TangentEditMode = Tangent.Out;
                            e.Use();
                        }
                    }

                    // Mouse up - clean up states
                    if (e.rawType == EventType.MouseUp && m_EditMode != EditMode.None)
                    {
                        m_EditMode = EditMode.None;
                    }

                    // Set cursors
                    {
                        EditorGUIUtility.AddCursorRect(hitRect, MouseCursor.MoveArrow);

                        if (k > 0 || state.loopInBounds)
                        {
                            EditorGUIUtility.AddCursorRect(inTangentHitRect, MouseCursor.RotateArrow);
                        }

                        if (k < length - 1 || state.loopInBounds)
                        {
                            EditorGUIUtility.AddCursorRect(outTangentHitrect, MouseCursor.RotateArrow);
                        }
                    }
                }
            }

            Handles.color = Color.white;
            SaveCurve(curve, animCurve);
        }
 public void Add(AnimationCurve curve, CurveState state)
 {
     _mCurves.Add(curve, state);
 }
Exemple #8
0
        void OnCurveGUI(Rect rect, SerializedProperty curve, CurveState state)
        {
            // Discard invisible curves
            if (!state.visible)
                return;

            var animCurve = curve.animationCurveValue;
            var keys = animCurve.keys;
            var length = keys.Length;

            // Curve drawing
            // Slightly dim non-editable curves
            var color = state.color;
            if (!state.editable)
                color.a *= 0.5f;

            Handles.color = color;
            var bounds = settings.bounds;

            if (length == 0)
            {
                var p1 = CurveToCanvas(new Vector3(bounds.xMin, state.zeroKeyConstantValue));
                var p2 = CurveToCanvas(new Vector3(bounds.xMax, state.zeroKeyConstantValue));
                Handles.DrawAAPolyLine(state.width, p1, p2);
            }
            else if (length == 1)
            {
                var p1 = CurveToCanvas(new Vector3(bounds.xMin, keys[0].value));
                var p2 = CurveToCanvas(new Vector3(bounds.xMax, keys[0].value));
                Handles.DrawAAPolyLine(state.width, p1, p2);
            }
            else
            {
                var prevKey = keys[0];
                for (int k = 1; k < length; k++)
                {
                    var key = keys[k];
                    var pts = BezierSegment(prevKey, key);

                    if (float.IsInfinity(prevKey.outTangent) || float.IsInfinity(key.inTangent))
                    {
                        var s = HardSegment(prevKey, key);
                        Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]);
                    }
                    else Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width);

                    prevKey = key;
                }

                // Curve extents & loops
                if (keys[0].time > bounds.xMin)
                {
                    if (state.loopInBounds)
                    {
                        var p1 = keys[length - 1];
                        p1.time -= settings.bounds.width;
                        var p2 = keys[0];
                        var pts = BezierSegment(p1, p2);

                        if (float.IsInfinity(p1.outTangent) || float.IsInfinity(p2.inTangent))
                        {
                            var s = HardSegment(p1, p2);
                            Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]);
                        }
                        else Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width);
                    }
                    else
                    {
                        var p1 = CurveToCanvas(new Vector3(bounds.xMin, keys[0].value));
                        var p2 = CurveToCanvas(keys[0]);
                        Handles.DrawAAPolyLine(state.width, p1, p2);
                    }
                }

                if (keys[length - 1].time < bounds.xMax)
                {
                    if (state.loopInBounds)
                    {
                        var p1 = keys[length - 1];
                        var p2 = keys[0];
                        p2.time += settings.bounds.width;
                        var pts = BezierSegment(p1, p2);

                        if (float.IsInfinity(p1.outTangent) || float.IsInfinity(p2.inTangent))
                        {
                            var s = HardSegment(p1, p2);
                            Handles.DrawAAPolyLine(state.width, s[0], s[1], s[2]);
                        }
                        else Handles.DrawBezier(pts[0], pts[3], pts[1], pts[2], color, null, state.width);
                    }
                    else
                    {
                        var p1 = CurveToCanvas(keys[length - 1]);
                        var p2 = CurveToCanvas(new Vector3(bounds.xMax, keys[length - 1].value));
                        Handles.DrawAAPolyLine(state.width, p1, p2);
                    }
                }
            }

            // Make sure selection is correct (undo can break it)
            bool isCurrentlySelectedCurve = curve == m_SelectedCurve;

            if (isCurrentlySelectedCurve && m_SelectedKeyframeIndex >= length)
                m_SelectedKeyframeIndex = -1;

            // Handles & keys
            for (int k = 0; k < length; k++)
            {
                bool isCurrentlySelectedKeyframe = k == m_SelectedKeyframeIndex;
                var e = Event.current;

                var pos = CurveToCanvas(keys[k]);
                var hitRect = new Rect(pos.x - 8f, pos.y - 8f, 16f, 16f);
                var offset = isCurrentlySelectedCurve
                    ? new RectOffset(5, 5, 5, 5)
                    : new RectOffset(6, 6, 6, 6);

                var outTangent = pos + CurveTangentToCanvas(keys[k].outTangent).normalized * 40f;
                var inTangent = pos - CurveTangentToCanvas(keys[k].inTangent).normalized * 40f;
                var inTangentHitRect = new Rect(inTangent.x - 7f, inTangent.y - 7f, 14f, 14f);
                var outTangentHitrect = new Rect(outTangent.x - 7f, outTangent.y - 7f, 14f, 14f);

                // Draw
                if (state.showNonEditableHandles)
                {
                    if (e.type == EventType.repaint)
                    {
                        var selectedColor = (isCurrentlySelectedCurve && isCurrentlySelectedKeyframe)
                            ? settings.selectionColor
                            : state.color;

                        // Keyframe
                        EditorGUI.DrawRect(offset.Remove(hitRect), selectedColor);

                        // Tangents
                        if (isCurrentlySelectedCurve && (!state.onlyShowHandlesOnSelection || (state.onlyShowHandlesOnSelection && isCurrentlySelectedKeyframe)))
                        {
                            Handles.color = selectedColor;

                            if (k > 0 || state.loopInBounds)
                            {
                                Handles.DrawAAPolyLine(state.handleWidth, pos, inTangent);
                                EditorGUI.DrawRect(offset.Remove(inTangentHitRect), selectedColor);
                            }

                            if (k < length - 1 || state.loopInBounds)
                            {
                                Handles.DrawAAPolyLine(state.handleWidth, pos, outTangent);
                                EditorGUI.DrawRect(offset.Remove(outTangentHitrect), selectedColor);
                            }
                        }
                    }
                }

                // Events
                if (state.editable)
                {
                    // Keyframe move
                    if (m_EditMode == EditMode.Moving && e.type == EventType.MouseDrag && isCurrentlySelectedCurve && isCurrentlySelectedKeyframe)
                    {
                        EditMoveKeyframe(animCurve, keys, k);
                    }

                    // Tangent editing
                    if (m_EditMode == EditMode.TangentEdit && e.type == EventType.MouseDrag && isCurrentlySelectedCurve && isCurrentlySelectedKeyframe)
                    {
                        bool alreadyBroken = !(Mathf.Approximately(keys[k].inTangent, keys[k].outTangent) || (float.IsInfinity(keys[k].inTangent) && float.IsInfinity(keys[k].outTangent)));
                        EditMoveTangent(animCurve, keys, k, m_TangentEditMode, e.shift || !(alreadyBroken || e.control));
                    }

                    // Keyframe selection
                    if (e.type == EventType.mouseDown && rect.Contains(e.mousePosition))
                    {
                        if (hitRect.Contains(e.mousePosition))
                        {
                            SelectKeyframe(curve, k);
                            m_EditMode = EditMode.Moving;
                            e.Use();
                        }
                    }

                    // Tangent selection & edit mode
                    if (e.type == EventType.mouseDown && rect.Contains(e.mousePosition))
                    {
                        if (inTangentHitRect.Contains(e.mousePosition) && (k > 0 || state.loopInBounds))
                        {
                            SelectKeyframe(curve, k);
                            m_EditMode = EditMode.TangentEdit;
                            m_TangentEditMode = Tangent.In;
                            e.Use();
                        }
                        else if (outTangentHitrect.Contains(e.mousePosition) && (k < length - 1 || state.loopInBounds))
                        {
                            SelectKeyframe(curve, k);
                            m_EditMode = EditMode.TangentEdit;
                            m_TangentEditMode = Tangent.Out;
                            e.Use();
                        }
                    }

                    // Mouse up - clean up states
                    if (e.rawType == EventType.MouseUp && m_EditMode != EditMode.None)
                    {
                        m_EditMode = EditMode.None;
                    }

                    // Set cursors
                    {
                        EditorGUIUtility.AddCursorRect(hitRect, MouseCursor.MoveArrow);

                        if (k > 0 || state.loopInBounds)
                            EditorGUIUtility.AddCursorRect(inTangentHitRect, MouseCursor.RotateArrow);

                        if (k < length - 1 || state.loopInBounds)
                            EditorGUIUtility.AddCursorRect(outTangentHitrect, MouseCursor.RotateArrow);
                    }
                }
            }

            Handles.color = Color.white;
            SaveCurve(curve, animCurve);
        }
Exemple #9
0
        public void SetCurveState(SerializedProperty curve, CurveState state)
        {
            if (!m_Curves.ContainsKey(curve))
                throw new KeyNotFoundException("curve");

            m_Curves[curve] = state;
        }
Exemple #10
0
        private void GenerateRoad()
        {
            _roadParams = new RoadParameters
            {
                MaxHeight                = 900,
                MaxCurve                 = 400,
                Length                   = 12,
                NumberOfZones            = 12,
                Curvy                    = 0.8,
                Mountiany                = 0.8,
                NumberOfSegmentsPerZone  = 250,
                RoadSegmentSize          = 5,
                NumberOfSegmentsPerColor = 4,
                OffRoadOffset            = 130,
            };
            _roadParams.Length = _roadParams.NumberOfZones * _roadParams.NumberOfSegmentsPerZone;

            _road      = new List <RoadSegment>();
            _roadZones = new List <RoadZone>();

            HeightState currentStateHeight = HeightState.Flat;
            CurveState  currentStateCurve  = CurveState.Straight;

            var currentHeight = 0.0;
            var currentCurve  = 0.0;
            var zones         = _roadParams.NumberOfZones;

            while (zones-- > 0)
            {
                var zone = new RoadZone(_roadParams.NumberOfSegmentsPerZone);

                // Generate current zone
                var finalHeight = 0.0;
                switch (currentStateHeight)
                {
                case HeightState.Flat:
                {
                    finalHeight = 0.0;
                    break;
                }

                case HeightState.Up:
                {
                    finalHeight = _roadParams.MaxHeight * _random.NextDouble();
                    break;
                }

                case HeightState.Down:
                {
                    finalHeight = -_roadParams.MaxHeight * _random.NextDouble();
                    break;
                }
                }

                var finalCurve = 0.0;
                switch (currentStateCurve)
                {
                case CurveState.Straight:
                {
                    finalCurve = 0.0;
                    break;
                }

                case CurveState.Left:
                {
                    finalCurve = -_roadParams.MaxCurve * _random.NextDouble();
                    break;
                }

                case CurveState.Right:
                {
                    finalCurve = _roadParams.MaxCurve * _random.NextDouble();
                    break;
                }
                }

                zone.AddCurve(currentStateCurve, currentCurve, finalCurve);
                zone.AddHeight(currentStateHeight, currentHeight, finalHeight);

                for (int i = 0; i < _roadParams.NumberOfSegmentsPerZone; i++)
                {
                    var segment = new RoadSegment
                    {
                        Height        = zone.StartHeight + (zone.HeightStep * i),
                        Curve         = zone.StartCurve + (zone.CurveStep * i),
                        SegmentSprite = SelectSegmentSprite(i)
                    };

                    _road.Add(segment);
                    zone.AddSegment(segment);
                }

                currentHeight = finalHeight;
                currentCurve  = finalCurve;

                currentStateHeight = SelectNextZoneHeightTransition();
                currentStateCurve  = SelectNextZoneCurveTransition();

                _roadZones.Add(zone);
            }
        }