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();
            }
        }
예제 #2
0
 public SpherePointKeyframe(SpherePointKeyframe keyframe) : base(keyframe.time)
 {
     spherePoint = new SpherePoint(
         keyframe.spherePoint.horizontalRotation,
         keyframe.spherePoint.verticalRotation);
     interpolationCurve     = keyframe.interpolationCurve;
     interpolationDirection = keyframe.interpolationDirection;
 }
예제 #3
0
        private void InsertKeyframeInSpherePointGroup(float time, SpherePointKeyframeGroup group)
        {
            SpherePointKeyframe previousKeyFrame = group.GetPreviousKeyFrame(time);
            SpherePointKeyframe newKeyFrame      = new SpherePointKeyframe(previousKeyFrame);

            newKeyFrame.time = time;
            group.AddKeyFrame(newKeyFrame);

            KeyframeInspectorWindow.SetKeyframeData(
                newKeyFrame, group, KeyframeInspectorWindow.KeyType.SpherePoint, m_ActiveSkyProfile);
        }
        public static float GetSpeedBetweenKeyframes(SpherePointKeyframe from, SpherePointKeyframe to)
        {
            float distance = Vector3.Angle(from.spherePoint.GetWorldDirection(), to.spherePoint.GetWorldDirection());
            float duration = GetDurationBetweenKeyframes(from, to);

            // Just in case duration is zero...
            if (duration == 0.0f)
            {
                duration = .00001f;
            }

            return(distance / duration);
        }
        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);
        }
        public static void MoveKeyframeTimeToMatchSpeed(SpherePointKeyframe keyframe, SpherePointKeyframe nextKeyframe, float speed)
        {
            // Solve for duration required to match a speed.
            float duration      = GetDistanceBetweenKeyframes(keyframe, nextKeyframe) / speed;
            float durationDelta = GetDurationBetweenKeyframes(keyframe, nextKeyframe) - duration;

            if (keyframe.time + durationDelta < 0)
            {
                keyframe.time = 1.0f - (keyframe.time + durationDelta);
            }
            else
            {
                keyframe.time += durationDelta;
            }

            keyframe.time = Mathf.Clamp01(keyframe.time);
        }
예제 #7
0
        private void ShowSpherePointKeyframesInSkybox(SpherePointKeyframeGroup group)
        {
            int debugPoints = 0;

            for (int i = 0; i < group.keyframes.Count; i++)
            {
                SpherePointKeyframe keyframe  = group.keyframes[i];
                Vector3             direction = keyframe.spherePoint.GetWorldDirection();
                float   isActiveKeyframe      = SkyEditorUtility.IsKeyframeActiveInInspector(keyframe) ? 1.0f : 0.0f;
                Vector4 pointData             = new Vector4(direction.x, direction.y, direction.z, isActiveKeyframe);

                if (i < MAX_DEBUG_POINTS)
                {
                    m_DebugPoints[i] = pointData;
                    debugPoints     += 1;
                }
            }

            ShowDebugPoints(m_DebugPoints, debugPoints);
        }
        public static void RenderSpherePointRow(Rect rect, SkyProfile profile, SpherePointKeyframeGroup group)
        {
            bool sortGroup = false;

            RenderColorGradients(rect, group);

            for (int i = 0; i < group.keyframes.Count; i++)
            {
                SpherePointKeyframe currentKey = group.GetKeyframe(i);

                // Track key marker mouse events and render.
                bool didSingleClick  = false;
                bool isDragging      = false;
                bool keyframeUpdated = false;
                SkyEditorUtility.DrawHorizontalKeyMarker(rect, currentKey, profile,
                                                         out didSingleClick, out isDragging, out keyframeUpdated);

                if (keyframeUpdated)
                {
                    sortGroup = true;
                }

                // Show the color keyframe property window.
                if (didSingleClick || isDragging)
                {
                    // Load info about this keyframe and show the editor window.
                    KeyframeInspectorWindow.SetKeyframeData(
                        currentKey, group, KeyframeInspectorWindow.KeyType.SpherePoint, profile);

                    if (didSingleClick)
                    {
                        KeyframeInspectorWindow.ShowWindow();
                    }
                }
            }

            if (sortGroup)
            {
                group.SortKeyframes();
            }
        }
예제 #9
0
        private bool RenderSpherePointPropertyGroup(ProfileGroupDefinition def)
        {
            EditorGUILayout.BeginHorizontal();
            bool valueChanged = false;

            SpherePointKeyframeGroup group = m_Profile.GetGroup <SpherePointKeyframeGroup>(def.propertyKey);

            if (m_Profile.IsManagedByTimeline(def.propertyKey))
            {
                EditorGUILayout.PrefixLabel(new GUIContent(def.groupName, def.tooltip));
                RenderManagedOnTimlineMessage();
            }
            else
            {
                SpherePointKeyframe frame = group.GetKeyframe(0);

                EditorGUILayout.BeginVertical();

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField(new GUIContent(group.name, def.tooltip));
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();

                EditorGUI.BeginChangeCheck();
                EditorGUI.indentLevel += 1;
                SpherePoint selectedPoint = SpherePointGUI.SpherePointField(
                    frame.spherePoint, true, frame.id);
                EditorGUI.indentLevel -= 1;
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(m_Profile, "Changed sphere point");
                    frame.spherePoint = selectedPoint;
                }

                EditorGUILayout.EndVertical();
            }

            EditorGUILayout.EndHorizontal();
            return(valueChanged);
        }
예제 #10
0
        private bool RenderSpherePointGUI()
        {
            bool didModify = false;

            SpherePointKeyframe spherePointKeyframe = keyframe as SpherePointKeyframe;

            if (spherePointKeyframe == null)
            {
                return(false);
            }

            EditorGUILayout.BeginHorizontal();
            EditorGUI.BeginChangeCheck();
            SpherePoint selectedSpherePoint = SpherePointGUI.SpherePointField(spherePointKeyframe.spherePoint, true, keyframe.id);

            if (EditorGUI.EndChangeCheck())
            {
                spherePointKeyframe.spherePoint = selectedSpherePoint;
                didModify = true;
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUI.BeginChangeCheck();
            GUIStyle style = GUI.skin.button;

            EditorGUILayout.PrefixLabel(
                new GUIContent("Normalize Speed",
                               "Adjust all keyframes so that there is a constant speed of animation between them."));
            GUILayout.Button(new GUIContent("Reposition All Keyframes..."), style);
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(profile, "Normalize keyframe speeds");
                didModify = true;
                SpherePointTimelineRow.RepositionKeyframesForConstantSpeed(group as SpherePointKeyframeGroup);
            }
            EditorGUILayout.EndHorizontal();

            return(didModify);
        }
        // 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);
        }
 public static float GetDistanceBetweenKeyframes(SpherePointKeyframe from, SpherePointKeyframe to)
 {
     return(Vector3.Angle(from.spherePoint.GetWorldDirection(), to.spherePoint.GetWorldDirection()));
 }