float ToAnimationClipTime(double globalTime) { if (m_Clip != null) { return((float)m_Clip.ToLocalTimeUnbound(globalTime)); } return((float)(globalTime - m_ClipData.start)); }
internal static bool ProcessPlayableAssetRecording(UndoPropertyModification mod, WindowState state, TimelineClip clip) { if (mod.currentValue == null) { return(false); } if (!clip.IsParameterAnimatable(mod.currentValue.propertyPath)) { return(false); } // don't use time global to local since it will possibly loop. double localTime = clip.ToLocalTimeUnbound(state.editSequence.time); if (localTime < 0) { return(false); } // grab the value from the current modification float fValue = 0; if (!float.TryParse(mod.currentValue.value, out fValue)) { // case 916913 -- 'Add Key' menu item will passes 'True' or 'False' (instead of 1, 0) // so we need a special case to parse the boolean string bool bValue = false; if (!bool.TryParse(mod.currentValue.value, out bValue)) { Debug.Assert(false, "Invalid type in PlayableAsset recording"); return(false); } fValue = bValue ? 1 : 0; } bool added = (clip.AddAnimatedParameterValueAt(mod.currentValue.propertyPath, fValue, (float)localTime)); if (added && AnimationMode.InAnimationMode()) { EditorCurveBinding binding = clip.GetCurveBinding(mod.previousValue.propertyPath); AnimationMode.AddPropertyModification(binding, mod.previousValue, true); clip.parentTrack.SetShowInlineCurves(true); if (state.GetWindow() != null && state.GetWindow().treeView != null) { state.GetWindow().treeView.CalculateRowRects(); } } return(added); }
public AnimationClip PrepareTrack(TrackAsset track, WindowState state, GameObject gameObject, out double startTime) { AnimationClip animationClip = null; // if we are not in clip mode, we simply use the track clip var animationTrack = (AnimationTrack)track; // ignore recording if we are in Legacy auto mode startTime = -1; var parentTrack = TimelineUtility.GetSceneReferenceTrack(track) as AnimationTrack; if (parentTrack != null && parentTrack.trackOffset == TrackOffset.Auto) { return(null); } if (!animationTrack.inClipMode) { var trackClip = animationTrack.GetOrCreateClip(); startTime = trackClip.frameRate * state.editSequence.time; // Make the first key be at time 0 of the clip if (trackClip.empty) { animationTrack.infiniteClipTimeOffset = 0; // state.time; animationTrack.infiniteClipPreExtrapolation = TimelineClip.ClipExtrapolation.Hold; animationTrack.infiniteClipPostExtrapolation = TimelineClip.ClipExtrapolation.Hold; } animationClip = trackClip; } else { TimelineClip activeClip = null; // if it fails, but returns no clip, we can add one. if (!track.FindRecordingClipAtTime(state.editSequence.time, out activeClip) && activeClip != null) { return(null); } if (activeClip == null) { activeClip = AddRecordableClip(track, state, state.editSequence.time); } var clip = activeClip.animationClip; // flags this as the clip being recorded for the track var clipTime = state.editSequence.time - activeClip.start; // if we are in the past if (clipTime < 0) { Undo.RegisterCompleteObjectUndo(clip, "Record Key"); UndoExtensions.RegisterTrack(track, "Prepend Key"); ShiftAnimationClip(clip, (float)-clipTime); activeClip.start = state.editSequence.time; activeClip.duration += -clipTime; clipTime = 0; } m_ClipTime = clipTime; recordClip = activeClip; startTime = recordClip.ToLocalTimeUnbound(state.editSequence.time) * clip.frameRate; m_needRebuildRects = clip.empty; animationClip = clip; } m_TargetClip = animationClip; m_CurveCount = GetCurveCount(animationClip); m_TrackHasPreviewComponents = animationTrack.hasPreviewComponents; return(animationClip); }