Ejemplo n.º 1
0
//----------------------------------------------------------------------------------------------------------------------    
    /// <inheritdoc/>
    public override ClipDrawOptions GetClipOptions(TimelineClip clip) {
        ClipDrawOptions         clipOptions = base.GetClipOptions(clip);
        SceneCachePlayableAsset asset       = clip.asset as SceneCachePlayableAsset;
        if (null == asset) {
            Debug.LogError("Asset is not a SceneCachePlayableAsset: " + clip.asset);
            return clipOptions;
        }
        
        SceneCacheClipData clipData = asset.GetBoundClipData();
        if (null == clipData) 
            return clipOptions;

        SceneCachePlayer scPlayer = asset.GetSceneCachePlayer();
        if (null == scPlayer) {
            clipOptions.errorText = NO_SCENE_CACHE_ASSIGNED_ERROR;
            return clipOptions;
        }

        LimitedAnimationController overrideLimitedAnimationController =asset.GetOverrideLimitedAnimationController();
        
        if (!scPlayer.IsLimitedAnimationOverrideable() && overrideLimitedAnimationController.IsEnabled()) {
            clipOptions.errorText = UNABLE_TO_OVERRIDE_LIMITED_ANIMATION_ERROR;
            return clipOptions;
        }

        clipOptions.tooltip = scPlayer.GetSceneCacheFilePath();

        return clipOptions;
    } 
Ejemplo n.º 2
0
//----------------------------------------------------------------------------------------------------------------------    
    //Called when a clip is changed by the Editor. (TrimStart, TrimEnd, etc)    
    public override void OnClipChanged(TimelineClip clip) {       
        base.OnClipChanged(clip);
        
        SceneCachePlayableAsset playableAsset = clip.asset as SceneCachePlayableAsset;
        if (null == playableAsset) {
            Debug.LogWarning("[MeshSync] Clip Internal Error: Asset is not SceneCache");
            return;            
        }
        
        //Check if the curves is null, which may happen if the clip is created using code ?
        if (null == clip.curves) {
            CreateClipCurve(clip);
        }        
        
        SceneCacheClipData clipData = playableAsset.GetBoundClipData() as SceneCacheClipData;
        if (null == clipData) {
            //The clip is not ready. Not deserialized yet
            return;
        }
        
               
        //Always apply clipCurves to clipData
        AnimationCurve curve = AnimationUtility.GetEditorCurve(clip.curves, SceneCachePlayableAsset.GetTimeCurveBinding());        
        clipData.SetAnimationCurve(curve);
        
    }    
//----------------------------------------------------------------------------------------------------------------------
    
    private void DrawLimitedAnimationGUI(SceneCachePlayableAsset scPlayableAsset) {
        SceneCachePlayer scPlayer = scPlayableAsset.GetSceneCachePlayer();
        
        bool disableScope = null == scPlayer;
        
        if (null != scPlayer) {
            disableScope |= (!scPlayer.IsLimitedAnimationOverrideable());
        }

        if (disableScope) {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.HelpBox(
                "Disabled because Limited Animation settings on the SceneCache GameObject is enabled, or the playback mode is set to interpolate", 
                MessageType.Warning
            );
            if (GUILayout.Button("Fix", GUILayout.Width(64), GUILayout.Height(36))) {
                scPlayer.AllowLimitedAnimationOverride();
                Repaint();
            }
            EditorGUILayout.EndHorizontal();
            
        }

        using (new EditorGUI.DisabledScope(disableScope)) {
            SceneCachePlayerEditorUtility.DrawLimitedAnimationGUI(scPlayableAsset.GetOverrideLimitedAnimationController(),
                m_scPlayableAsset, scPlayer);
        }
        
    }
Ejemplo n.º 4
0
        public IEnumerator CreatePlayableAsset()
        {
            EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects);

            //Add director
            GameObject       directorGo = new GameObject("Director");
            PlayableDirector director   = directorGo.AddComponent <PlayableDirector>();

            //Setup scene cache
            GameObject       sceneCacheGo     = new GameObject();
            SceneCachePlayer sceneCachePlayer = sceneCacheGo.AddComponent <SceneCachePlayer>();

            Assert.IsFalse(sceneCachePlayer.IsSceneCacheOpened());
            SceneCachePlayerEditorUtility.ChangeSceneCacheFile(sceneCachePlayer, Path.GetFullPath(MeshSyncTestEditorConstants.CUBE_TEST_DATA_PATH));


            //Create timeline asset
            TimelineAsset asset = ScriptableObject.CreateInstance <TimelineAsset>();

            director.playableAsset = asset;

            //Create PlayableAsset/Track/ etc
            SceneCachePlayableAsset playableAsset   = ScriptableObject.CreateInstance <SceneCachePlayableAsset>();
            SceneCacheTrack         sceneCacheTrack = asset.CreateTrack <SceneCacheTrack>(null, "TestSceneCacheTrack");
            TimelineClip            clip            = sceneCacheTrack.CreateDefaultClip();

            clip.asset = playableAsset;
            director.SetReferenceValue(playableAsset.GetSceneCachePlayerRef().exposedName, sceneCachePlayer);


            //Select gameObject and open Timeline Window. This will trigger the TimelineWindow's update etc.
            EditorApplication.ExecuteMenuItem("Window/Sequencing/Timeline");
            Selection.activeTransform = directorGo.transform;
            yield return(null);

            director.time = 0;
            yield return(null);

            Assert.AreEqual(0, sceneCachePlayer.GetRequestedNormalizedTime());
            double timePerFrame = 1.0f / sceneCacheTrack.timelineAsset.editorSettings.fps;

            double directorTime = clip.start + clip.duration - timePerFrame;

            SetDirectorTime(director, directorTime);
            yield return(null);

            //Check clipData and curve
            SceneCacheClipData clipData = playableAsset.GetBoundClipData();

            Assert.IsNotNull(clipData);
            AnimationCurve curve = clipData.GetAnimationCurve();

            Assert.IsNotNull(curve);
            float normalizedTime = curve.Evaluate((float)directorTime);


            Assert.AreEqual(normalizedTime, sceneCachePlayer.GetRequestedNormalizedTime());
        }
Ejemplo n.º 5
0
//----------------------------------------------------------------------------------------------------------------------

    private void CreateClipCurve(TimelineClip clip) {        
        clip.CreateCurves("Curves: " + clip.displayName);
        
        //Init dummy linear curve
        AnimationCurve curve = AnimationCurve.Linear(0f,0f,(float)clip.duration,1f);
        AnimationUtility.SetEditorCurve(clip.curves, SceneCachePlayableAsset.GetTimeCurveBinding(),curve);
        TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved );
        
        
    }
        private static AnimationCurve VerifyAnimationCurve(TimelineClip clip)
        {
            SceneCachePlayableAsset sceneCachePlayableAsset = clip.asset as SceneCachePlayableAsset;

            Assert.IsNotNull(sceneCachePlayableAsset);
            AnimationCurve curve = sceneCachePlayableAsset.GetAnimationCurve();

            Assert.IsNotNull(curve);
            return(curve);
        }
        public IEnumerator EnsureMatchingAndLimitedFramesAreLoadedToScene()
        {
            InitTest(true, out PlayableDirector director, out SceneCachePlayer sceneCachePlayer, out TimelineClip clip0);
            yield return(null);


            ISceneCacheInfo scInfo = sceneCachePlayer.ExtractSceneCacheInfo(forceOpen: true);

            Assert.IsNotNull(scInfo);
            int    numFrames    = scInfo.GetNumFrames();
            double timePerFrame = 1.0f / scInfo.GetSampleRate();

            //Setup clip0 duration
            int halfFrames = Mathf.FloorToInt(numFrames * 0.5f);

            clip0.duration = halfFrames * timePerFrame;

            //Setup clip1
            TimelineClip clip1 = clip0.GetParentTrack().CreateClip <SceneCachePlayableAsset>();

            clip1.start    = clip0.start + clip0.duration;
            clip1.clipIn   = clip0.duration;
            clip1.duration = clip0.duration;
            SceneCachePlayableAsset playableAsset1 = clip1.asset as SceneCachePlayableAsset;

            Assert.IsNotNull(playableAsset1);
            director.SetReferenceValue(playableAsset1.GetSceneCachePlayerRef().exposedName, sceneCachePlayer);

            TimelineEditorUtility.RefreshTimelineEditor(RefreshReason.ContentsAddedOrRemoved | RefreshReason.WindowNeedsRedraw | RefreshReason.ContentsModified);
            yield return(null);

            //Setup Limited Animation
            const int NUM_FRAMES_TO_HOLD = 3;
            const int OFFSET             = 1;

            LimitedAnimationController limitedAnimationController1 = playableAsset1.GetOverrideLimitedAnimationController();

            limitedAnimationController1.Enable(NUM_FRAMES_TO_HOLD, OFFSET);

            yield return(IterateAllSceneCacheFrames(director, clip0, sceneCachePlayer, (int timelineFrame) => {
                EditorApplication.isPaused = true;
                Assert.AreEqual(timelineFrame, sceneCachePlayer.GetFrame());
            }));

            yield return(IterateAllSceneCacheFrames(director, clip1, sceneCachePlayer, (int timelineFrame) => {
                int shownFrame = sceneCachePlayer.GetFrame();
                if (shownFrame == (scInfo.GetNumFrames() - 1)) //clamped to the end frame
                {
                    return;
                }

                Assert.Zero(shownFrame % NUM_FRAMES_TO_HOLD - OFFSET);
            }));
        }
Ejemplo n.º 8
0
//----------------------------------------------------------------------------------------------------------------------    

    internal static TimelineClip AddSceneCacheTrackAndClip(PlayableDirector director, string trackName, 
        SceneCachePlayer sceneCachePlayer) 
    {
        TimelineAsset timelineAsset = director.playableAsset as TimelineAsset;
        Assert.IsNotNull(timelineAsset);
    
        SceneCacheTrack         sceneCacheTrack = timelineAsset.CreateTrack<SceneCacheTrack>(null, trackName);
        TimelineClip            clip            = sceneCacheTrack.CreateDefaultClip();
        SceneCachePlayableAsset playableAsset = clip.asset as SceneCachePlayableAsset;
        Assert.IsNotNull(playableAsset);
        director.SetReferenceValue(playableAsset.GetSceneCachePlayerRef().exposedName, sceneCachePlayer );
        return clip;
    }
Ejemplo n.º 9
0
//----------------------------------------------------------------------------------------------------------------------    
    /// <inheritdoc/>
    public override void OnCreate(TimelineClip clip, TrackAsset track, TimelineClip clonedFrom) {
        
        SceneCachePlayableAsset asset = clip.asset as SceneCachePlayableAsset;
        if (null == asset) {
            Debug.LogError("[MeshSync] Asset is not a SceneCachePlayableAsset: " + clip.asset);
            return;
        }
        
        SceneCachePlayerConfig config = MeshSyncProjectSettings.GetOrCreateSettings().GetDefaultSceneCachePlayerConfig();        
        asset.SetSnapToFrame((SnapToFrame) config.TimelineSnapToFrame);

        //OnCreate() is called before the clip is assigned to the track, but we need the track for creating curves.
        clip.TryMoveToTrack(track);
                       
    }
Ejemplo n.º 10
0
//----------------------------------------------------------------------------------------------------------------------    
    /// <inheritdoc/>
    public override void OnCreate(TimelineClip clip, TrackAsset track, TimelineClip clonedFrom) {
                
        SceneCachePlayableAsset asset = clip.asset as SceneCachePlayableAsset;
        if (null == asset) {
            Debug.LogError("[MeshSync] Asset is not a SceneCachePlayableAsset: " + clip.asset);
            return;
        }
        
        //Track can be null during copy and paste
        if (null != track) {
            //This callback occurs before the clip is assigned to the track, but we need the track for creating curves.
            clip.TryMoveToTrack(track);
        }

        asset.Init(updateClipDurationOnCreatePlayable: null == clonedFrom);
    }
//----------------------------------------------------------------------------------------------------------------------    
    /// <inheritdoc/>
    public override void OnCreate(TimelineClip clip, TrackAsset track, TimelineClip clonedFrom) {
        
        SceneCachePlayableAsset asset = clip.asset as SceneCachePlayableAsset;
        if (null == asset) {
            Debug.LogError("[MeshSync] Asset is not a SceneCachePlayableAsset: " + clip.asset);
            return;
        }

        //OnCreate() is called before the clip is assigned to the track, but we need the track for creating curves.
        clip.parentTrack = track;
                       
        //If the clip already has curves (because of cloning, etc), then we don't set anything
        if (null == clip.curves) {
            CreateClipCurve(clip);
        }        
    }
        public IEnumerator EnsureLimitedFramesAreLoadedToScene()
        {
            InitTest(true, out PlayableDirector director, out SceneCachePlayer sceneCachePlayer, out TimelineClip clip);
            yield return(null);

            //Setup Limited Animation
            const int NUM_FRAMES_TO_HOLD = 3;
            const int OFFSET             = 1;

            SceneCachePlayableAsset sceneCachePlayableAsset = clip.asset as SceneCachePlayableAsset;

            Assert.IsNotNull(sceneCachePlayableAsset);
            LimitedAnimationController limitedAnimationController = sceneCachePlayableAsset.GetOverrideLimitedAnimationController();

            limitedAnimationController.Enable(NUM_FRAMES_TO_HOLD, OFFSET);

            yield return(IterateAllSceneCacheFrames(director, clip, sceneCachePlayer, (int timelineFrame) => {
                int shownFrame = sceneCachePlayer.GetFrame();
                Assert.Zero(shownFrame % NUM_FRAMES_TO_HOLD - OFFSET);
            }));
        }
        public IEnumerator ChangeSceneCache()
        {
            InitTest(true, out PlayableDirector _, out SceneCachePlayer scPlayer, out TimelineClip clip);
            yield return(null);

            SceneCachePlayableAsset sceneCachePlayableAsset = clip.asset as SceneCachePlayableAsset;

            Assert.IsNotNull(sceneCachePlayableAsset);

            sceneCachePlayableAsset.SetSceneCachePlayerInEditor(null);
            double halfDuration = clip.duration * 0.5f;

            clip.duration = halfDuration;
            TimelineEditor.Refresh(RefreshReason.ContentsModified);
            yield return(null);

            sceneCachePlayableAsset.SetSceneCachePlayerInEditor(scPlayer);
            TimelineEditor.Refresh(RefreshReason.ContentsModified);
            yield return(null);

            Assert.IsTrue(Mathf.Approximately((float)halfDuration, (float)clip.duration), "Clip Duration has been reset.");
        }
Ejemplo n.º 14
0
//----------------------------------------------------------------------------------------------------------------------
    
    /// <inheritdoc/>
    public override void DrawBackground(TimelineClip clip, ClipBackgroundRegion region) {
        base.DrawBackground(clip, region);
        
        SceneCachePlayableAsset asset = clip.asset as SceneCachePlayableAsset;
        if (null == asset) {
            Debug.LogError("Asset is not a SceneCachePlayableAsset: " + clip.asset);
            return;
        }
        
        SceneCacheClipData clipData = asset.GetBoundClipData();
        if (null == clipData)
            return;

        LimitedAnimationController limitedAnimationController = asset.GetOverrideLimitedAnimationController();
        if (!limitedAnimationController.IsEnabled()) {
            return;
        }

        int numFrames = limitedAnimationController.GetNumFramesToHold();
        int offset    = limitedAnimationController.GetFrameOffset();
            
        GUIStyle style = new GUIStyle(GUI.skin.label) {
            alignment = TextAnchor.LowerRight,
            normal    = {
                textColor = new Color(0.3f,0.9f,0.3f),
            }
        };
        GUIContent laContent = new GUIContent($"Limited: {numFrames}, {offset}");
        
        Vector2 laContentSize = style.CalcSize(laContent);
        Rect rect = region.position;
        if (rect.width <= laContentSize.x * 2) //2: arbitrary
            return;
        
        EditorGUI.LabelField(rect, laContent, style);

        
    }