private void DrawTangent(AnimationKeyframeRenderData keyframeRenderData, USInternalKeyframe keyframe) { var FinalRenderPosition = keyframeRenderData.RenderPosition; FinalRenderPosition.x = (FinalRenderPosition.x * XScale) - XScroll; var leftTangentRect = new Rect(keyframeRenderData.LeftTangentEnd.x - 5, keyframeRenderData.LeftTangentEnd.y - 4, 10, 10); var rightTangentRect = new Rect(keyframeRenderData.RightTangentEnd.x - 5, keyframeRenderData.RightTangentEnd.y - 4, 10, 10); if (keyframeRenderData.HasLeftTangent) { var inAngle = -Mathf.Rad2Deg * Mathf.Atan(keyframe.InTangent); Vector2 inDir = Quaternion.Euler(0, 0, inAngle) * Vector2.right; var ratio = DisplayArea.height / DisplayArea.width; inDir.y = inDir.y * ratio; inDir.Normalize(); keyframeRenderData.LeftTangentEnd = FinalRenderPosition + (-inDir * AnimationCurveEditorUtility.TANGENT_LENGTH); using (new GUIChangeColor(keyframeRenderData.LeftTangentColor)) GUI.Label(leftTangentRect, AnimationCurveEditorUtility.KeyframeTexture); } if (keyframeRenderData.HasRightTangent) { var outAngle = -Mathf.Rad2Deg * Mathf.Atan(keyframe.OutTangent); Vector2 outDir = Quaternion.Euler(0, 0, outAngle) * Vector2.right; var ratio = DisplayArea.height / DisplayArea.width; outDir.y = outDir.y * ratio; outDir.Normalize(); keyframeRenderData.RightTangentEnd = FinalRenderPosition + (outDir * AnimationCurveEditorUtility.TANGENT_LENGTH); using (new GUIChangeColor(keyframeRenderData.RightTangentColor)) GUI.Label(rightTangentRect, AnimationCurveEditorUtility.KeyframeTexture); } if (Event.current.type == EventType.MouseDown && leftTangentRect.Contains(Event.current.mousePosition)) { SelectTangent(keyframeRenderData, 0); } if (Event.current.type == EventType.MouseDown && rightTangentRect.Contains(Event.current.mousePosition)) { SelectTangent(keyframeRenderData, 1); } if (Event.current.type == EventType.MouseDrag && SelectedTangent != -1) { DragTangent(keyframeRenderData, 0); } if (Event.current.type == EventType.MouseDrag && SelectedTangent != -1) { DragTangent(keyframeRenderData, 1); } if (Event.current.rawType == EventType.MouseUp && SelectedTangent != -1) { Event.current.Use(); SelectedTangent = -1; } }
private void RebuildCachedKeyframeInformation(USInternalKeyframe keyframe) { cachedKeyframePositions[keyframe] = new AnimationKeyframeRenderData(); var keyframeIndex = keyframe.curve.Keys.ToList().FindIndex(element => element == keyframe); var keyframeRatio = (keyframe.Value - MinDisplayY) / (MaxDisplayY - MinDisplayY); var keyframePos = new Vector2(DisplayArea.width * (keyframe.Time / Duration), DisplayArea.height * keyframeRatio); keyframePos.y = DisplayArea.height - keyframePos.y; cachedKeyframePositions[keyframe].RenderPosition = keyframePos; cachedKeyframePositions[keyframe].RenderRect = new Rect(cachedKeyframePositions[keyframe].RenderPosition.x - 6, cachedKeyframePositions[keyframe].RenderPosition.y - 6, 16, 16); cachedKeyframePositions[keyframe].HasLeftTangent = false; cachedKeyframePositions[keyframe].HasRightTangent = false; // Evaluate, stepCount steps per curve section. if (keyframeIndex != 0) { var prevKeyframe = keyframe.curve.Keys[keyframeIndex - 1]; var timeDifference = keyframe.Time - prevKeyframe.Time; var timeStep = timeDifference / AnimationCurveEditorUtility.CURVE_KEYFRAME_STEP_COUNT; var startTime = prevKeyframe.Time; for (var n = 0; n <= AnimationCurveEditorUtility.CURVE_KEYFRAME_STEP_COUNT; n++) { var nextEvaluationTime = startTime + timeStep; var prevSampleValue = keyframe.curve.Evaluate(startTime); var sampleValue = keyframe.curve.Evaluate(nextEvaluationTime); var prevRatio = (prevSampleValue - MinDisplayY) / (MaxDisplayY - MinDisplayY); var nextRatio = (sampleValue - MinDisplayY) / (MaxDisplayY - MinDisplayY); var startPos = new Vector2(DisplayArea.width * (startTime / Duration), DisplayArea.height * prevRatio); var endPos = new Vector2(DisplayArea.width * (nextEvaluationTime / Duration), DisplayArea.height * nextRatio); startPos.y = DisplayArea.height - startPos.y; endPos.y = DisplayArea.height - endPos.y; cachedKeyframePositions[keyframe].CurveSegments.Add(startPos); startTime = nextEvaluationTime; } } if (keyframeIndex < keyframe.curve.Keys.Count - 1) { cachedKeyframePositions[keyframe].HasRightTangent = true; } if (keyframeIndex > 0) { cachedKeyframePositions[keyframe].HasLeftTangent = true; } }
public static void KeyframeLabel(USInternalKeyframe keyframe, AnimationKeyframeRenderData renderData, bool useCurrentValue, float xScroll, float xScale) { var isSelected = renderData.IsKeyframeSelected; var FinalRenderPosition = renderData.RenderPosition; FinalRenderPosition.x = (FinalRenderPosition.x * xScale) - xScroll; renderData.RenderRect = new Rect(FinalRenderPosition.x - 6, renderData.RenderPosition.y - 6, 16, 16); using (new Shared.GUIChangeColor(isSelected ? Color.yellow : (useCurrentValue ? Color.red : Color.white))) GUI.Label(renderData.RenderRect, AnimationCurveEditorUtility.KeyframeTexture); renderData.IsMouseOverKeyframe = false; if (renderData.RenderRect.Contains(Event.current.mousePosition)) { renderData.IsMouseOverKeyframe = true; } }
private void SelectTangent(AnimationKeyframeRenderData keyframeRenderData, int tangentIndex) { USUndoManager.PropertyChange(this, "Select Tangent"); SelectedTangent = tangentIndex; Event.current.Use(); }
private void DragTangent(AnimationKeyframeRenderData keyframeRenderData, int tangentIndex) { AreCurvesDirty = true; var keyframe = SelectedObjects[0] as USInternalKeyframe; USUndoManager.PropertyChange(keyframe, "Alter keyframe"); Vector3 direction = (Event.current.mousePosition - keyframeRenderData.RenderPosition).normalized; var ratio = DisplayArea.height / DisplayArea.width; direction.y = direction.y / ratio; direction.Normalize(); var needsFlip = direction.y > 0.0f; var angle = Vector2.Angle(Vector2.right, direction); if (SelectedTangent == 1 && angle >= 90.0f) { angle = 90.0f; } if (SelectedTangent == 0 && angle <= 90.0f) { angle = 90.0f; } angle = Mathf.Deg2Rad * angle; angle = Mathf.Tan(angle); if (needsFlip) { angle = -1.0f * angle; } if (angle > 10000.0f || angle < -10000.0f) { angle = Mathf.Infinity; } if (!keyframe.BrokenTangents) { if (SelectedTangent == 0) { keyframe.InTangent = angle; keyframe.OutTangent = angle; } if (SelectedTangent == 1) { keyframe.OutTangent = angle; keyframe.InTangent = angle; } } else { if (SelectedTangent == 0) { keyframe.InTangent = angle; } if (SelectedTangent == 1) { keyframe.OutTangent = angle; } } var keyframeIndex = keyframe.curve.Keys.ToList().FindIndex(element => element == keyframe); RebuildCachedKeyframeInformation(keyframe); if (keyframeIndex != 0) { RebuildCachedKeyframeInformation(keyframe.curve.Keys[keyframeIndex - 1]); } if (keyframeIndex < keyframe.curve.Keys.Count - 1) { RebuildCachedKeyframeInformation(keyframe.curve.Keys[keyframeIndex + 1]); } keyframe.curve.BuildAnimationCurveFromInternalCurve(); Event.current.Use(); }