public static void RepositionKeyframesForConstantSpeed(SpherePointKeyframeGroup group) { if (group.GetKeyFrameCount() < 2) { return; } // Because time is always 1, no need to divide by it. float totalDistance = GetTotalDistanceBetweenKeyframes(group); float targetSpeed = totalDistance; int keyFrameCount = group.GetKeyFrameCount(); for (int j = 0; j < keyFrameCount; j++) { for (int i = keyFrameCount - 2; i >= 0; i--) { int nextIndex = i + 1; SpherePointKeyframe keyframe = group.keyframes[i]; SpherePointKeyframe nextKeyframe = group.keyframes[nextIndex]; MoveKeyframeTimeToMatchSpeed(keyframe, nextKeyframe, targetSpeed); } // This is a hack, we resort and re-calculated edges since durations were changed. group.SortKeyframes(); } }
public static float GetTotalDistanceBetweenKeyframes(SpherePointKeyframeGroup group) { float total = 0; for (int i = 0; i < group.GetKeyFrameCount(); i++) { int nextIndex = (i + 1) % group.GetKeyFrameCount(); SpherePointKeyframe currentKeyframe = group.keyframes[i]; SpherePointKeyframe nextKeyframe = group.keyframes[nextIndex]; total += GetDistanceBetweenKeyframes(currentKeyframe, nextKeyframe); } return(total); }
// Color based on last edge speed. public static List <Vector4> GenerateColorSpeedPoints(SpherePointKeyframeGroup group) { List <Vector4> colorPoints = new List <Vector4>(); if (group.GetKeyFrameCount() <= 1) { colorPoints.Add(new Vector4(0.0f, m_AvgColor.r, m_AvgColor.g, m_AvgColor.b)); colorPoints.Add(new Vector4(1.0f, m_AvgColor.r, m_AvgColor.g, m_AvgColor.b)); return(colorPoints); } float gradientOffset = .02f; const float maxSpeed = 1200.0f; for (int i = 0; i < group.keyframes.Count; i++) { int nextIndex = (i + 1) % group.GetKeyFrameCount(); SpherePointKeyframe currentKeyframe = group.keyframes[i]; SpherePointKeyframe nextKeyframe = group.keyframes[nextIndex]; // Last keyframe has special rules if (i == group.keyframes.Count - 1) { float speed = GetSpeedBetweenKeyframes(currentKeyframe, nextKeyframe); Color speedColor = Color.Lerp(m_AvgColor, m_MaxColor, speed / maxSpeed); float gradientBeginTime = currentKeyframe.time + gradientOffset; float gradientEndTime = 1.0f; if (gradientBeginTime >= 1.0f) { gradientBeginTime = currentKeyframe.time; } colorPoints.Add( new Vector4(gradientBeginTime, speedColor.r, speedColor.g, speedColor.b)); colorPoints.Add( new Vector4(gradientEndTime, speedColor.r, speedColor.g, speedColor.b)); // Now bridge gap if any to first keyframe. if (!SkyEditorUtility.IsKeyFrameAtStart(nextKeyframe)) { gradientBeginTime = 0.0f; gradientEndTime = nextKeyframe.time - gradientOffset; if (gradientEndTime < 0) { gradientEndTime = nextKeyframe.time; } colorPoints.Insert(0, new Vector4(gradientEndTime, speedColor.r, speedColor.g, speedColor.b)); colorPoints.Insert(0, new Vector4(gradientBeginTime, speedColor.r, speedColor.g, speedColor.b)); } else { colorPoints.Insert( 0, new Vector4(0, speedColor.r, speedColor.g, speedColor.b)); } } else { float gradientBeginTime = currentKeyframe.time + gradientOffset; float gradientEndTime = nextKeyframe.time - gradientOffset; // Need to play with these to see how they look. Maybe use a percentage between them instead? if (gradientBeginTime >= nextKeyframe.time) { gradientBeginTime = currentKeyframe.time; } if (gradientEndTime <= currentKeyframe.time) { gradientEndTime = nextKeyframe.time; } float speed = GetSpeedBetweenKeyframes(currentKeyframe, nextKeyframe); Color speedColor = Color.Lerp(m_AvgColor, m_MaxColor, speed / maxSpeed); colorPoints.Add( new Vector4(gradientBeginTime, speedColor.r, speedColor.g, speedColor.b)); colorPoints.Add( new Vector4(gradientEndTime, speedColor.r, speedColor.g, speedColor.b)); } } return(colorPoints); }