/** * @brief Adds a new track to the timeline * @param range A track by default is added with 1 event * @T Event type that the track will hold * @sa RemoveTrack */ public FTrack Add <T>(FrameRange range) where T : FEvent { FTrack track = FTrack.Create <T>(); Add(track); // int id = _tracks.Count; // // _tracks.Add( track ); // // track.SetTimeline( this ); // track.SetId( id ); // // if( !Sequence.IsStopped ) // track.Init(); FEvent evt = FEvent.Create <T>(range); track.Add(evt); return(track); }
public bool CanAdd(FEvent evt, FrameRange newRange) { for (int i = 0; i != _events.Count; ++i) { if (_events[i].Start > newRange.End) { break; } if (_events[i] == evt) { continue; } if (_events[i].FrameRange.Collides(newRange)) { return(false); } } return(true); }
/// @brief Returns what kind of overlap it has with \e range. /// @note Assumes They are both valid public FrameRangeOverlap GetOverlap(FrameRange range) { if (range._start >= _start) { // contains, left or none if (range._end <= _end) { return(FrameRangeOverlap.ContainsFull); } else { if (range._start > _end) { return(FrameRangeOverlap.MissOnRight); } return(FrameRangeOverlap.ContainsStart); } } else { // contained, right or none if (range._end < _start) { return(FrameRangeOverlap.MissOnLeft); } else { if (range._end > _end) { return(FrameRangeOverlap.IsContained); } return(FrameRangeOverlap.ContainsEnd); } } }
/// @brief Returns if the ranges overlap, i.e. touching return true /// @note Assumes They are both valid public bool Overlaps(FrameRange range) { return(range.End >= _start && range.Start <= _end); }
/// @brief Returns if the ranges intersect, i.e. touching returns false /// @note Assumes They are both valid public bool Collides(FrameRange range) { return(_start < range._end && _end > range._start); // return (range.start > start && range.start < end) || (range.end > start && range.end < end ); }
/// @brief Use this function if you want to do something to the event when the frame range /// changed, e.g. adjust some variables to the new event size. /// @param oldFrameRange Previous FrameRange, the current one is set on the event. protected virtual void OnFrameRangeChanged(FrameRange oldFrameRange) { }
protected override bool BuildInternal() { _tracksCached = GetAnimationTracks(); _validFrameRanges.Clear(); if (_tracksCached.Count == 0) { return(false); } // build preview #if FLUX_DEBUG Debug.LogWarning("Creating Preview"); #endif FSequence sequence = Track.Sequence; if (_tracksCached[0].Snapshot != null) { _tracksCached[0].Snapshot.Restore(); } _snapshot = Application.isPlaying ? null : new GameObjectSnapshot(Track.Owner.gameObject); bool ownerIsActive = Track.Owner.gameObject.activeSelf; if (!ownerIsActive) { HideFlags hideFlags = Track.Owner.gameObject.hideFlags; Track.Owner.gameObject.hideFlags |= HideFlags.DontSave; Track.Owner.gameObject.SetActive(true); Track.Owner.gameObject.hideFlags = hideFlags; } float speed = sequence.Speed; if (speed != 1) { sequence.Speed = 1f; } Animator.speed = 1f; int currentFrame = sequence.CurrentFrame; bool isPlaying = sequence.IsPlaying; if (!sequence.IsStopped) { sequence.Stop(); } if (!sequence.IsInit) { sequence.Init(); } FrameRange currentFrameRange = new FrameRange(); foreach (FAnimationTrack animTrack in _tracksCached) { animTrack.Cache = null; animTrack.Stop(); // we need to force stop them to clear the currentEvent index } // RuntimeAnimatorController controller = Animator.runtimeAnimatorController; // Animator.runtimeAnimatorController = null; // Animator.runtimeAnimatorController = controller; // set culling to get around Unity bug of recording at the start AnimatorCullingMode animatorCullingMode = Animator.cullingMode; Animator.cullingMode = AnimatorCullingMode.AlwaysAnimate; Animator.enabled = true; for (int i = 0; i != Animator.layerCount; ++i) { Animator.SetLayerWeight(i, 0f); } Animator.StartRecording(-1); bool success = Animator.recorderMode == AnimatorRecorderMode.Record; if (success) { Animator.enabled = false; float delta = 1f / sequence.FrameRate; int frame = 0; while (frame <= sequence.Length) { bool wasEnabled = Animator.enabled; foreach (FAnimationTrack animTrack in _tracksCached) { animTrack.UpdateEvents(frame, frame * delta); } if (wasEnabled) { currentFrameRange.End += 1; if (Animator.enabled) { Animator.Update(delta); } else { Animator.enabled = true; Animator.Update(delta); Animator.enabled = false; _validFrameRanges.Add(currentFrameRange); } } else if (Animator.enabled) { Animator.Update(0); currentFrameRange = new FrameRange(frame, frame); } ++frame; } foreach (FAnimationTrack animTrack in _tracksCached) { animTrack.Cache = this; } Track = _tracksCached[0]; Animator.StopRecording(); sequence.Stop(true); if (_snapshot != null) { _snapshot.Restore(); } } if (!ownerIsActive) { HideFlags hideFlags = Track.Owner.gameObject.hideFlags; Track.Owner.gameObject.hideFlags |= HideFlags.DontSave; Track.Owner.gameObject.SetActive(false); Track.Owner.gameObject.hideFlags = hideFlags; } if (speed != 1) { sequence.Speed = speed; } Animator.cullingMode = animatorCullingMode; if (currentFrame >= 0) { if (isPlaying) { sequence.Play(currentFrame); } else { sequence.SetCurrentFrame(currentFrame); } } return(success); }
/// <summary> /// 帧范围改变时调用 /// </summary> /// <param name="oldFrameRange">前一个帧范围</param> protected virtual void OnFrameRangeChanged(FrameRange oldFrameRange, int oldSingleFrame) { }
public bool Collides(FrameRange range) { return(_start < range._end && _end > range._start); }