/// <summary>
        /// Create motion state.
        /// </summary>
        /// <param name="playableGraph">Playable graph.</param>
        /// <param name="clip">Animation clip.</param>
        /// <param name="isLoop">Animation is loop.</param>
        /// <param name="speed">Animation speed.</param>
        public static CubismMotionState CreateCubismMotionState(PlayableGraph playableGraph, AnimationClip clip, bool isLoop = true, float speed = 1.0f)
        {
            var ret = new CubismMotionState();

            ret.Clip = clip;

            // Create animation clip mixer.
            ret.ClipMixer = AnimationMixerPlayable.Create(playableGraph, 2);
            ret.ClipMixer.SetSpeed(speed);

            // Connect AnimationClip Playable
            ret.ClipPlayable = AnimationClipPlayable.Create(playableGraph, ret.Clip);

            if (!isLoop)
            {
                ret.ClipPlayable.SetDuration(clip.length - 0.0001f);
            }

            ret.ClipMixer.ConnectInput(0, ret.ClipPlayable, 0);
            ret.ClipMixer.SetInputWeight(0, 1.0f);

            return(ret);
        }
Пример #2
0
        Playable CreateInfiniteTrackPlayable(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree, AppliedOffsetMode mode)
        {
            if (m_InfiniteClip == null)
            {
                return(Playable.Null);
            }

            var mixer = AnimationMixerPlayable.Create(graph, 1);

            // In infinite mode, we always force the loop mode of the clip off because the clip keys are offset in infinite mode
            //  which causes loop to behave different.
            // The inline curve editor never shows loops in infinite mode.
            var playable = AnimationPlayableAsset.CreatePlayable(graph, m_InfiniteClip, m_InfiniteClipOffsetPosition, m_InfiniteClipOffsetEulerAngles, false, mode, infiniteClipApplyFootIK, AnimationPlayableAsset.LoopMode.Off);

            if (playable.IsValid())
            {
                tree.Add(new InfiniteRuntimeClip(playable));
                graph.Connect(playable, 0, mixer, 0);
                mixer.SetInputWeight(0, 1.0f);
            }

            return(ApplyTrackOffset(graph, mixer, go, mode));
        }
    public static int PlayMixer_s(IntPtr l)
    {
        int result;

        try
        {
            Animator animator;
            LuaObject.checkType <Animator>(l, 1, out animator);
            int inputCount;
            LuaObject.checkType(l, 2, out inputCount);
            PlayableGraph          playableGraph;
            AnimationMixerPlayable animationMixerPlayable = AnimationPlayableUtilities.PlayMixer(animator, inputCount, out playableGraph);
            LuaObject.pushValue(l, true);
            LuaObject.pushValue(l, animationMixerPlayable);
            LuaObject.pushValue(l, playableGraph);
            result = 3;
        }
        catch (Exception e)
        {
            result = LuaObject.error(l, e);
        }
        return(result);
    }
Пример #4
0
        public Mixer(PlayableGraph playableGraph, ref AnimationLayerMixerPlayable animationLayerMixerPlayable, AnimationCurve blendingCurve, List <AnimationClip> animationClips)
        {
            animationMixerPlayable = AnimationMixerPlayable.Create(playableGraph, animationClips.Count, true);
            animationLayerMixerPlayable.AddInput(animationMixerPlayable, 0, 1);
            this.blendingCurve = blendingCurve;

            for (var i = 0; i < animationClips.Count; i++)
            {
                var animationClipPlayable = AnimationClipPlayable.Create(playableGraph, animationClips[i]);
                animationMixerPlayable.ConnectInput(i, animationClipPlayable, 0);

                animationClipPlayables.Add(animationClipPlayable);
                index.Add(animationClips[i].name, i);
                times.Add(animationClips[i].name, animationClips[i].length);
            }

            Observable
            .EveryUpdate()
            .Subscribe(_ =>
            {
                for (var i = 0; i < animationClipPlayables.Count; i++)
                {
                    animationMixerPlayable.SetInputWeight(i, 0);
                }
                if (string.IsNullOrEmpty(prev))
                {
                    animationMixerPlayable.SetInputWeight(index[next], 1.0f);
                }
                else
                {
                    var dt    = Time.timeSinceLevelLoad - currentTime;
                    var ratio = blendingCurve.Evaluate(dt);
                    animationMixerPlayable.SetInputWeight(index[prev], 1 - ratio);
                    animationMixerPlayable.SetInputWeight(index[next], ratio);
                }
            });
        }
Пример #5
0
    // Use this for initialization
    void Start()
    {
        playableGraph = PlayableGraph.Create("My Graph");
        playableGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
        var playableOutput = AnimationPlayableOutput.Create(playableGraph, "animation output", GetComponent <Animator>());


        clipPlayable  = AnimationClipPlayable.Create(playableGraph, clip);
        clipPlayable2 = AnimationClipPlayable.Create(playableGraph, clip2);
        mixer         = AnimationMixerPlayable.Create(playableGraph, 2);

        playableOutput.SetSourcePlayable(mixer, 0);
        playableGraph.Connect(clipPlayable2, 0, mixer, 0);
        playableGraph.Connect(clipPlayable, 0, mixer, 1);

        //mixer.AddInput(clipPlayable, 0);
        //mixer.AddInput(clipPlayable2, 0);

        var p = Playable.Create(playableGraph);

        // Plays the Graph.

        playableGraph.Play();
    }
Пример #6
0
        public static void SetPreviewObject(GameObject a_previewObj)
        {
            if (a_previewObj == null)
            {
                Debug.LogError("Trying to set preview object in the preview " +
                               "scene but the passed object is null. Aborting");
                return;
            }

            if (PreviewObject != null)
            {
                PlayableGraph.Destroy();
                GameObject.DestroyImmediate(PreviewObject);
            }

            PreviewObject           = GameObject.Instantiate(a_previewObj);
            PreviewObject.hideFlags = HideFlags.DontSaveInEditor;

            PreviewObject.name = "PreviewModel_MxM";
            PreviewAnimator    = PreviewObject.GetComponent <Animator>();

            if (PreviewAnimator == null)
            {
                PreviewAnimator = PreviewObject.AddComponent <Animator>();
            }

            PlayableGraph = PlayableGraph.Create("PreviewCharacter");
            PlayableGraph.SetTimeUpdateMode(DirectorUpdateMode.Manual);

            var playableOutput = AnimationPlayableOutput.Create(PlayableGraph,
                                                                "Animation", PreviewAnimator);

            Mixer = AnimationMixerPlayable.Create(PlayableGraph, 1, true);
            playableOutput.SetSourcePlayable(Mixer);
            Mixer.SetInputWeight(0, 1f);
        }
    private void Start()
    {
        // Creates the graph, the mixer and binds them to the Animator.
        playableGraph = PlayableGraph.Create();

        var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", GetComponent <Animator>());

        mixerPlayable = AnimationMixerPlayable.Create(playableGraph, 2);

        playableOutput.SetSourcePlayable(mixerPlayable);

        // Creates AnimationClipPlayable and connects them to the mixer.

        var clipPlayable0 = AnimationClipPlayable.Create(playableGraph, clip0);

        var clipPlayable1 = AnimationClipPlayable.Create(playableGraph, clip1);

        playableGraph.Connect(clipPlayable0, 0, mixerPlayable, 0);

        playableGraph.Connect(clipPlayable1, 0, mixerPlayable, 1);

        // Plays the Graph.
        playableGraph.Play();
    }
    // Use this for initialization
    void Start()
    {
        // Create the PlayableGraph.
        m_Graph = PlayableGraph.Create();

        // Add an AnimationPlayableOutput to the graph.
        var animOutput = AnimationPlayableOutput.Create(m_Graph, "AnimationOutput", GetComponent <Animator>());

        // Add an AnimationMixerPlayable to the graph.
        var mixerPlayable = AnimationMixerPlayable.Create(m_Graph, 2, false);

        // Add two AnimationClipPlayable to the graph.
        var clipPlayableA = AnimationClipPlayable.Create(m_Graph, clipA);
        var clipPlayableB = AnimationClipPlayable.Create(m_Graph, clipB);

        // Add a custom PlayableBehaviour to the graph.
        // This behavior will change the weights of the mixer dynamically.
        var blenderPlayable = ScriptPlayable <BlenderPlayableBehaviour> .Create(m_Graph, 1);

        blenderPlayable.GetBehaviour().mixerPlayable = mixerPlayable;

        // Create the topology, connect the AnimationClipPlayable to the
        // AnimationMixerPlayable.  Also add the BlenderPlayableBehaviour.
        m_Graph.Connect(clipPlayableA, 0, mixerPlayable, 0);
        m_Graph.Connect(clipPlayableB, 0, mixerPlayable, 1);
        m_Graph.Connect(mixerPlayable, 0, blenderPlayable, 0);

        // Use the ScriptPlayable as the source for the AnimationPlayableOutput.
        // Since it's a ScriptPlayable, also set the source input port to make the
        // passthrough to the AnimationMixerPlayable.
        animOutput.SetSourcePlayable(blenderPlayable);
        animOutput.SetSourceInputPort(0);

        // Play the graph.
        m_Graph.Play();
    }
Пример #9
0
        public Instance(EntityManager entityManager, Entity owner, PlayableGraph graph, Entity animStateOwner, AnimGraph_InAir settings)
        {
            m_settings       = settings;
            m_EntityManager  = entityManager;
            m_Owner          = owner;
            m_AnimStateOwner = animStateOwner;

            GameDebug.Assert(entityManager.HasComponent <Character>(m_AnimStateOwner), "Owner has no Character component");
            m_character = entityManager.GetComponentObject <Character>(m_AnimStateOwner);

            m_mainMixer = AnimationMixerPlayable.Create(graph);

            m_animInAir = AnimationClipPlayable.Create(graph, settings.animInAir);
            m_animInAir.Play();
            m_animInAir.SetApplyFootIK(false);
            inAirPort = m_mainMixer.AddInput(m_animInAir, 0);

            m_animLandAntic = AnimationClipPlayable.Create(graph, settings.animLandAntic);
            m_animInAir.Play();
            m_animLandAntic.SetApplyFootIK(false);
            landAnticPort = m_mainMixer.AddInput(m_animLandAntic, 0);

            m_layerMixer = AnimationLayerMixerPlayable.Create(graph);
            var port = m_layerMixer.AddInput(m_mainMixer, 0);

            m_layerMixer.SetInputWeight(port, 1);

            // Aim
            if (settings.animAimDownToUp != null)
            {
                m_aimHandler = new AimVerticalHandler(m_layerMixer, settings.animAimDownToUp);
            }

            // Actions
            m_actionAnimationHandler = new ActionAnimationHandler(m_layerMixer, settings.actionAnimations);
        }
Пример #10
0
        Playable CompileTrackPlayable(PlayableGraph graph, AnimationTrack track, GameObject go, IntervalTree <RuntimeElement> tree, AppliedOffsetMode mode)
        {
            var mixer = AnimationMixerPlayable.Create(graph, track.clips.Length);

            for (int i = 0; i < track.clips.Length; i++)
            {
                var c     = track.clips[i];
                var asset = c.asset as PlayableAsset;
                if (asset == null)
                {
                    continue;
                }

                var animationAsset = asset as AnimationPlayableAsset;
                if (animationAsset != null)
                {
                    animationAsset.appliedOffsetMode = mode;
                }

                var source = asset.CreatePlayable(graph, go);
                if (source.IsValid())
                {
                    var clip = new RuntimeClip(c, source, mixer);
                    tree.Add(clip);
                    graph.Connect(source, 0, mixer, i);
                    mixer.SetInputWeight(i, 0.0f);
                }
            }

            if (!track.AnimatesRootTransform())
            {
                return(mixer);
            }

            return(ApplyTrackOffset(graph, mixer, go, mode));
        }
Пример #11
0
        void Awake()
        {
            var animator = GetComponent <Animator>();

            _playableGraph = PlayableGraph.Create();
            _playableGraph.SetTimeUpdateMode(DirectorUpdateMode.Manual);
            playableOutput = AnimationPlayableOutput.Create(_playableGraph, "Animation", animator);

            mixerPlayable = AnimationMixerPlayable.Create(_playableGraph, 1);


            if (AnimationPlayLayers.Length > 1)
            {//如果有多层混合
                layerMixerPlayable = AnimationLayerMixerPlayable.Create(_playableGraph, 1);
                _playableGraph.Connect(mixerPlayable, 0, layerMixerPlayable, 0);
                playableOutput.SetSourcePlayable(layerMixerPlayable);
                layerMixerPlayable.SetInputWeight(0, 1f);
            }
            else
            {
                playableOutput.SetSourcePlayable(mixerPlayable);
            }
            _playableGraph.Play();
        }
Пример #12
0
        /************************************************************************************************************************/

        /// <summary>Creates and assigns the <see cref="AnimationMixerPlayable"/> managed by this layer.</summary>
        protected override void CreatePlayable(out Playable playable) => playable = AnimationMixerPlayable.Create(Root._Graph);
Пример #13
0
 protected virtual Playable CreateAnimationPlayable(PlayableGraph graph, GameObject owner)
 {
     return(AnimationMixerPlayable.Create(graph));
 }
Пример #14
0
            AnimationClipPlayable CreateAimPlayable(PlayableGraph graph, AnimationClip clip, AnimationMixerPlayable mixer, AimMixerPort mixerPort)
            {
                AnimationClipPlayable playable = AnimationClipPlayable.Create(graph, clip);

                playable.Pause();
                playable.SetDuration(clip.length);
                graph.Connect(playable, 0, mixer, (int)mixerPort);
                return(playable);
            }
Пример #15
0
            static AnimationClipPlayable CreateTurnPlayable(PlayableGraph graph, AnimationClip clip, AnimationMixerPlayable mixer, LocoMixerPort mixerPort)
            {
                AnimationClipPlayable playable = AnimationClipPlayable.Create(graph, clip);

                playable.SetApplyFootIK(true);
                playable.Pause();
                playable.SetDuration(clip.length);

                graph.Connect(playable, 0, mixer, (int)mixerPort);
                mixer.SetInputWeight((int)mixerPort, 0.0f);

                return(playable);
            }
    //private float mainLoopTriggerTime = 1.0f;           // Time over which a main loop is interpolated with itself. [TODO] Should be made relative to main clip duration, as it will behave strangely for small durations.

    /*
     * Awake
     */
    private void Awake()
    {
        animator        = GetComponent <Animator>();
        goToEmotionList = new List <GoToEmotionEntry>();

        currentlyPlayingClips = new List <IFAClip>();

        // Create Playable Graph
        playableGraph = PlayableGraph.Create("ClairePlayableGraph");
        playableGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
        var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", animator);

        // Create Top Level Layer Mixer
        AnimationLayerMixerPlayable mixerLayerPlayable = AnimationLayerMixerPlayable.Create(playableGraph, 2);

        playableOutput.SetSourcePlayable(mixerLayerPlayable);

        // Create an Emotion Mixer
        int numberOfClips = 0;

        for (int i = 0; i < emotionObjects.Count; i++)
        {
            for (int j = 0; j < emotionObjects[i].animationGroupList.Count; j++)
            {
                if (emotionObjects[i].animationGroupList[j].main)
                {
                    numberOfClips++;
                }
                if (emotionObjects[i].animationGroupList[j].transitionIn)
                {
                    numberOfClips++;
                }
            }
        }
        mixerEmotionPlayable = AnimationMixerPlayable.Create(playableGraph, numberOfClips);    // Second argument sets number of inputs for clips to connect.

        // Wrap AnimController
        runtimeAnimController = animator.runtimeAnimatorController;
        var runtimeAnimControllerPlayable = AnimatorControllerPlayable.Create(playableGraph, runtimeAnimController);

        // Connect to Top Level Layer Mixer
        playableGraph.Connect(runtimeAnimControllerPlayable, 0, mixerLayerPlayable, 0);
        playableGraph.Connect(mixerEmotionPlayable, 0, mixerLayerPlayable, 1);
        mixerLayerPlayable.SetInputWeight(0, 1.0f);
        mixerLayerPlayable.SetInputWeight(1, 1.0f);
        mixerLayerPlayable.SetLayerMaskFromAvatarMask(1, headMask);
        //mixerLayerPlayable.SetLayerAdditive(1, true);

        // 1. Wraps each clip in a playable and connects them to the emotion mixer
        // 2. Also populate "playablesDict" to later be able to access the AnimationClipPlayables by their Index in the emotionMixer
        // 3. Main animations are not connected directly: Instead another MixerPlayable (mainMixer) is connected.
        //    The main playable is copied and both the original and copy are connected to the new MainMixer.
        //    This is to allow for smoothly looping main animations
        playablesDict = new Dictionary <string, int>();      // String: "Name"+"Index of Emotion Variation"; Int: Index in mixerEmotionPlayable
        int playablesCount     = 0;
        int tempPlayablesCount = 0;

        for (int i = 0; i < emotionObjects.Count; i++)
        {
            tempPlayablesCount = playablesCount;
            for (int j = 0; j < emotionObjects[i].animationGroupList.Count; j++)
            {
                if (emotionObjects[i].animationGroupList[j].main)
                {
                    playablesDict.Add(emotionObjects[i].name + j, playablesCount);
                    AnimationMixerPlayable mainMixer = AnimationMixerPlayable.Create(playableGraph, 2);
                    //var mainMixerBehaviour = ScriptPlayable<IFAMainMixerBehaviour>.Create(playableGraph, 1);                                    // Throwing a behaviour controller between emotionMixer and mainMixer
                    //mainMixerBehaviour.GetBehaviour().constructor2(mainMixer, mainLoopTriggerTime, mainMixerMainIndex, mainMixerCopyIndex);     // To automize looping of the main clip
                    //playableGraph.Connect(mainMixerBehaviour, 0, mixerEmotionPlayable, playablesCount);
                    playableGraph.Connect(mainMixer, 0, mixerEmotionPlayable, playablesCount);
                    playablesCount++;

                    AnimationClipPlayable main = AnimationClipPlayable.Create(playableGraph, emotionObjects[i].animationGroupList[j].main);
                    playableGraph.Connect(main, 0, mainMixer, mainMixerMainIndex);
                    mainMixer.SetInputWeight(mainMixerMainIndex, 1.0f);  // Set first clip to active
                    main.SetDuration(emotionObjects[i].animationGroupList[j].main.length);

                    AnimationClipPlayable mainCopy = AnimationClipPlayable.Create(playableGraph, emotionObjects[i].animationGroupList[j].main);
                    playableGraph.Connect(mainCopy, 0, mainMixer, mainMixerCopyIndex);
                    mainMixer.SetInputWeight(mainMixerCopyIndex, 0.1f);  // Set second clip to inactive
                    mainCopy.SetDuration(emotionObjects[i].animationGroupList[j].main.length);
                }

                if (emotionObjects[i].animationGroupList[j].transitionIn)
                {
                    playablesDict.Add(emotionObjects[i].name + "TransitionIn" + j, playablesCount);
                    AnimationClipPlayable transition = AnimationClipPlayable.Create(playableGraph, emotionObjects[i].animationGroupList[j].transitionIn);
                    playableGraph.Connect(transition, 0, mixerEmotionPlayable, playablesCount);

                    transition.SetDuration(emotionObjects[i].animationGroupList[j].transitionIn.length);
                    playablesCount++;
                }
            }

            // If an emotion has any animationClips, it can be transitioned to
            if (tempPlayablesCount < playablesCount)
            {
                goToEmotionList.Add(new GoToEmotionEntry(emotionObjects[i].name, false, i));
            }
        }

        // Unrelated to Playables; For Display Purposes
        if (GOWithDrawGraphOnImage)
        {
            drawGraphOnImage = GOWithDrawGraphOnImage.GetComponent <DrawGraphOnImage>();
        }
    }
Пример #17
0
        public CharacterAnimGraph_3PStand(EntityManager entityManager, Entity owner, PlayableGraph graph, Entity animStateOwner, AnimGraph_Stand template)
        {
            if (s_Instances == null)
            {
                s_Instances = new List <CharacterAnimGraph_3PStand>(16);
            }

            s_Instances.Add(this);


            m_template       = template;
            m_EntityManager  = entityManager;
            m_Owner          = owner;
            m_AnimStateOwner = animStateOwner;

            GameDebug.Assert(entityManager.HasComponent <Animator>(owner), "Owner has no Animator component");
            var animator = entityManager.GetComponentObject <Animator>(owner);

            GameDebug.Assert(entityManager.HasComponent <Skeleton>(owner), "Owner has no Skeleton component");
            var skeleton = entityManager.GetComponentObject <Skeleton>(owner);

            GameDebug.Assert(entityManager.HasComponent <CharPredictedStateData>(m_AnimStateOwner), "Owner has no CharPredictedState component");

            var leftToes  = skeleton.bones[skeleton.GetBoneIndex(template.leftToeBone.GetHashCode())];
            var rightToes = skeleton.bones[skeleton.GetBoneIndex(template.rightToeBone.GetHashCode())];

            // Locomotion mixer and loco animation
            m_locomotionMixer = AnimationMixerPlayable.Create(graph, (int)LocoMixerPort.Count);

            // Idle
            m_animIdle = AnimationClipPlayable.Create(graph, template.animIdle);
            m_animIdle.SetApplyFootIK(true);
            graph.Connect(m_animIdle, 0, m_locomotionMixer, (int)LocoMixerPort.Idle);
            m_locomotionMixer.SetInputWeight((int)LocoMixerPort.Idle, 1.0f);

            // Turns and trasitions
            m_animTurnL = CreateTurnAnim(graph, template.animTurnL, LocoMixerPort.TurnL);
            m_animTurnR = CreateTurnAnim(graph, template.animTurnR, LocoMixerPort.TurnR);

            var ports = new int[] { (int)LocoMixerPort.Idle, (int)LocoMixerPort.TurnL, (int)LocoMixerPort.TurnR };

            m_Transition = new SimpleTranstion <AnimationMixerPlayable>(m_locomotionMixer, ports);

            // Foot IK
            if (m_template.animTurnL.events.Length != 0)
            {
                m_LeftTurnFootFalls  = ExtractFootFalls(m_template.animTurnL);
                m_RightTurnFootFalls = ExtractFootFalls(m_template.animTurnR);
            }

            var ikJob = new FootIkJob
            {
                settings = m_template.footIK,
                leftToe  = animator.BindStreamTransform(leftToes),
                rightToe = animator.BindStreamTransform(rightToes)
            };

            m_footIk = AnimationScriptPlayable.Create(graph, ikJob, 1);
            graph.Connect(m_locomotionMixer, 0, m_footIk, 0);
            m_footIk.SetInputWeight(0, 1f);

            m_defaultLayer  = LayerMask.NameToLayer("Default");
            m_playerLayer   = LayerMask.NameToLayer("collision_player");
            m_platformLayer = LayerMask.NameToLayer("Platform");

            m_mask = 1 << m_defaultLayer | 1 << m_playerLayer | 1 << m_platformLayer;

            // Aim and Aim mixer
            m_aimMixer = AnimationMixerPlayable.Create(graph, (int)AimMixerPort.Count, true);

            m_animAimLeft  = CreateAimAnim(graph, template.animAimLeft, AimMixerPort.AimLeft);
            m_animAimMid   = CreateAimAnim(graph, template.animAimMid, AimMixerPort.AimMid);
            m_animAimRight = CreateAimAnim(graph, template.animAimRight, AimMixerPort.AimRight);

            // Setup other additive mixer
            m_additiveMixer = AnimationLayerMixerPlayable.Create(graph);

            var locoMixerPort = m_additiveMixer.AddInput(m_footIk, 0);

            m_additiveMixer.SetInputWeight(locoMixerPort, 1);

            var aimMixerPort = m_additiveMixer.AddInput(m_aimMixer, 0);

            m_additiveMixer.SetInputWeight(aimMixerPort, 1);
            m_additiveMixer.SetLayerAdditive((uint)aimMixerPort, true);

            // Actions
            m_actionAnimationHandler = new ActionAnimationHandler(m_additiveMixer, template.actionAnimations);

            m_ReloadActionAnimation = m_actionAnimationHandler.GetActionAnimation(CharPredictedStateData.Action.Reloading);

            // Shoot pose
            m_animShootPose = AnimationClipPlayable.Create(graph, template.animShootPose);
            m_animShootPose.SetApplyFootIK(false);
            m_animShootPose.SetDuration(template.animShootPose.length);
            m_animShootPose.Pause();
            m_ShootPosePort = m_additiveMixer.AddInput(m_animShootPose, 0);
            m_additiveMixer.SetInputWeight(m_ShootPosePort, 0.0f);
            m_additiveMixer.SetLayerAdditive((uint)m_ShootPosePort, true);
        }
Пример #18
0
        internal override Playable OnCreateClipPlayableGraph(PlayableGraph graph, GameObject go, IntervalTree <RuntimeElement> tree)
        {
            if (isSubTrack)
            {
                throw new InvalidOperationException("Nested animation tracks should never be asked to create a graph directly");
            }

            List <AnimationTrack> flattenTracks = new List <AnimationTrack>();

            if (CanCompileClips())
            {
                flattenTracks.Add(this);
            }


            bool animatesRootTransform = AnimatesRootTransform();

            foreach (var subTrack in GetChildTracks())
            {
                var child = subTrack as AnimationTrack;
                if (child != null && child.CanCompileClips())
                {
                    animatesRootTransform |= child.AnimatesRootTransform();
                    flattenTracks.Add(child);
                }
            }

            // figure out which mode to apply
            AppliedOffsetMode mode = GetOffsetMode(go, animatesRootTransform);
            var layerMixer         = CreateGroupMixer(graph, go, flattenTracks.Count);

            for (int c = 0; c < flattenTracks.Count; c++)
            {
                var compiledTrackPlayable = flattenTracks[c].inClipMode ?
                                            CompileTrackPlayable(graph, flattenTracks[c], go, tree, mode) :
                                            flattenTracks[c].CreateInfiniteTrackPlayable(graph, go, tree, mode);
                graph.Connect(compiledTrackPlayable, 0, layerMixer, c);
                layerMixer.SetInputWeight(c, flattenTracks[c].inClipMode ? 0 : 1);
                if (flattenTracks[c].applyAvatarMask && flattenTracks[c].avatarMask != null)
                {
                    layerMixer.SetLayerMaskFromAvatarMask((uint)c, flattenTracks[c].avatarMask);
                }
            }

            Playable mixer = (Playable)layerMixer;

#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                var motionXMixer = AnimationMixerPlayable.Create(graph, 2);

                var      animator     = GetBinding(go != null ? go.GetComponent <PlayableDirector>() : null);
                Playable blendDefault = Playable.Null;
                if (animator != null && animator.isHuman)
                {
                    blendDefault = AnimationClipPlayable.Create(graph, GetDefaultHumanoidClip());
                }
                else
                {
                    blendDefault = AnimationPosePlayable.Create(graph);
                    ((AnimationPosePlayable)blendDefault).SetReadDefaultPose(true);
                }

                var offsetPlayable = AnimationOffsetPlayable.Create(graph, m_SceneOffsetPosition, Quaternion.Euler(m_SceneOffsetRotation), 1);

                graph.Connect(blendDefault, 0, offsetPlayable, 0);
                graph.Connect(layerMixer, 0, motionXMixer, 0);
                graph.Connect(offsetPlayable, 0, motionXMixer, 1);

                offsetPlayable.SetInputWeight(0, 1.0f);
                motionXMixer.SetInputWeight(1, 1.0f);
                motionXMixer.SetInputWeight(0, 0.0f);

                mixer = (Playable)motionXMixer;
            }
#endif

            // motionX playable not required in scene offset mode, or root transform mode
            if (!RequiresMotionXPlayable(mode, go))
            {
                return(mixer);
            }

            // If we are animating a root transform, add the motionX to delta playable as the root node
            var motionXToDelta = AnimationMotionXToDeltaPlayable.Create(graph);
            graph.Connect(mixer, 0, motionXToDelta, 0);
            motionXToDelta.SetInputWeight(0, 1.0f);
            motionXToDelta.SetAbsoluteMotion(UsesAbsoluteMotion(mode));
            return(motionXToDelta);
        }
Пример #19
0
        public void GenerateRootLookupTable()
        {
            AnimationClip primaryClip = this.TargetClip;

            if (primaryClip != null)
            {
                if (m_targetPrefab == null)
                {
                    if (m_targetPreProcessData != null)
                    {
                        m_targetPrefab = m_targetPreProcessData.Prefab;
                    }
                    else if(m_targetAnimModule != null)
                    {
                        m_targetPrefab = m_targetPreProcessData.Prefab;
                    }
                }

                if (m_targetPrefab != null)
                {
                    if (m_rootPosLookupTable == null)
                        m_rootPosLookupTable = new List<Vector3>();

                    if (m_rootRotLookupTable == null)
                        m_rootRotLookupTable = new List<Quaternion>();

                    if (m_rootSpeedLookupTable == null)
                        m_rootSpeedLookupTable = new List<float>();

                    m_rootPosLookupTable.Clear();
                    m_rootRotLookupTable.Clear();
                    m_rootSpeedLookupTable.Clear();

                    //Instantiate prefab and setup playable graph
                    GameObject previewPrefab = Instantiate(m_targetPrefab);
                    Animator previewAnimator = previewPrefab.GetComponent<Animator>();

                    if (previewAnimator == null)
                    {
                        previewAnimator = previewPrefab.AddComponent<Animator>();
                        previewAnimator.applyRootMotion = true;
                    }

                    PlayableGraph playableGraph = PlayableGraph.Create();
                    playableGraph.SetTimeUpdateMode(DirectorUpdateMode.Manual);

                    var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", previewAnimator);
                    AnimationMixerPlayable animationMixer = AnimationMixerPlayable.Create(playableGraph, 1, true);
                    playableOutput.SetSourcePlayable(animationMixer);
                    var playableClip = AnimationClipPlayable.Create(playableGraph, primaryClip);
                    animationMixer.ConnectInput(0, playableClip, 0);
                    animationMixer.SetInputWeight(0, 1f);
                    playableClip.SetTime(0.0);
                    playableClip.SetTime(0.0);

                    previewPrefab.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
                    playableGraph.Evaluate(0f);

                    double sampleRate = 1.0 / primaryClip.frameRate;

                    //Fill the lookup table with root positions
                    for (double animTime = 0.0; animTime <= primaryClip.length; animTime += sampleRate)
                    {
                        m_rootPosLookupTable.Add(previewPrefab.transform.position);
                        m_rootRotLookupTable.Add(previewPrefab.transform.rotation);
                        playableGraph.Evaluate((float)sampleRate);
                    }

                    playableGraph.Destroy();
                    GameObject.DestroyImmediate(previewPrefab);


                    if (m_rootPosLookupTable.Count > 1)
                    {
                        //Generate the linear speed lookup table
                        for (int i = 1; i < m_rootPosLookupTable.Count; ++i)
                        {
                            Vector3 startPos = m_rootPosLookupTable[i - 1];
                            Vector3 endPos = m_rootPosLookupTable[i];

                            m_rootSpeedLookupTable.Add(Vector3.Distance(endPos, startPos) / (float)sampleRate);
                        }
                    }
                    else
                    {
                        m_rootSpeedLookupTable.Add(0f);
                    }

                    m_rootSpeedLookupTable.Insert(0, m_rootSpeedLookupTable[0]);
                }
            }
        }
 public static ReductionSyntax <PlayableSyntax> Add(
     this PlayableGraph graph, ref AnimationMixerPlayable playable, int count)
 {
     playable = AnimationMixerPlayable.Create(graph, count);
     return(PlayableSyntax.Create(graph, playable));
 }
Пример #21
0
    void AttachMixerToAnimationPlayableOutput(AnimationMixerPlayable mixer, PlayableGraph g)
    {
        var playableOutput = g.GetOutput(0);

        playableOutput.SetSourcePlayable(mixerPlayable);
    }
Пример #22
0
        public BlendedAnimationLayer(PlayableGraph PlayableGraph, AnimationLayerMixerPlayable parentAnimationLayerMixerPlayable,
                                     int layerId, BlendedAnimationInput BlendedAnimationInput, Func <float> InputWeightProvider) : base(layerId, parentAnimationLayerMixerPlayable)
        {
            this.BlendedAnimationInput = BlendedAnimationInput;
            this.BlendedAnimationClips = BlendedAnimationInput.BlendedAnimationClips.ConvertAll(i => i.ToBlendedAnimationClip());

            //create a playable mixer
            this.AnimationMixerPlayable = AnimationMixerPlayable.Create(PlayableGraph);

            foreach (var blendedAnimationClip in  this.BlendedAnimationClips)
            {
                var animationClipPlayable = AnimationClipPlayable.Create(PlayableGraph, blendedAnimationClip.AnimationClip);
                animationClipPlayable.SetApplyFootIK(false);
                animationClipPlayable.SetApplyPlayableIK(false);
                blendedAnimationClip.InputHandler = PlayableExtensions.AddInput(this.AnimationMixerPlayable, animationClipPlayable, 0);
                PlayableExtensions.Play(animationClipPlayable);
                blendedAnimationClip.AnimationClipPlayable = animationClipPlayable;
            }

            //calculate blendings
            for (var i = 0; i < this.BlendedAnimationClips.Count; i++)
            {
                if (i == 0)
                {
                    this.BlendedAnimationClips[i].Blending = this.BlendedAnimationClips[i].Blending.SetWeightTimePoints(
                        AnimationWeightStartIncreasingTime: 0f,
                        AnimationWeightEndIncreasingTime:  this.BlendedAnimationClips[i].WeightTime,
                        AnimationWeightStartDecreasingTime:  this.BlendedAnimationClips[i].WeightTime,
                        AnimationWeightEndDecreasingTime:  this.BlendedAnimationClips[i + 1].WeightTime
                        );
                }
                else if (i == this.BlendedAnimationClips.Count - 1)
                {
                    this.BlendedAnimationClips[i].Blending = this.BlendedAnimationClips[i].Blending.SetWeightTimePoints(
                        AnimationWeightStartIncreasingTime:  this.BlendedAnimationClips[i - 1].WeightTime,
                        AnimationWeightEndIncreasingTime:  this.BlendedAnimationClips[i].WeightTime,
                        AnimationWeightStartDecreasingTime:  this.BlendedAnimationClips[i].WeightTime,
                        AnimationWeightEndDecreasingTime: 1f
                        );
                }
                else
                {
                    this.BlendedAnimationClips[i].Blending = this.BlendedAnimationClips[i].Blending.SetWeightTimePoints(
                        AnimationWeightStartIncreasingTime:  this.BlendedAnimationClips[i - 1].WeightTime,
                        AnimationWeightEndIncreasingTime:  this.BlendedAnimationClips[i].WeightTime,
                        AnimationWeightStartDecreasingTime:  this.BlendedAnimationClips[i].WeightTime,
                        AnimationWeightEndDecreasingTime:  this.BlendedAnimationClips[i + 1].WeightTime
                        );
                }
            }

            this.Inputhandler = PlayableExtensions.AddInput(parentAnimationLayerMixerPlayable, this.AnimationMixerPlayable, 0);
            parentAnimationLayerMixerPlayable.SetLayerAdditive((uint)layerId, BlendedAnimationInput.IsAdditive);
            if (BlendedAnimationInput.AvatarMask != null)
            {
                parentAnimationLayerMixerPlayable.SetLayerMaskFromAvatarMask((uint)layerId, BlendedAnimationInput.AvatarMask);
            }

            if (InputWeightProvider != null)
            {
                this.inputWeightProvider = InputWeightProvider;
            }
        }
            public AnimationMixerPlayable AddMixerPlayable() => default; // 0x00A06B90-0x00A06DB0

            public void SetMixerPlayable_OutputWeight(AnimationMixerPlayable mixerPlayable, float weight)
            {
            }                                                                                                            // 0x00A06DB0-0x00A06E30
Пример #24
0
    private void UpdateStates(float deltaTime)
    {
        mustUpdateWeights.Clear();
        totalWeights.Clear();

        for (int i = 0; i < m_States.Count; i++)
        {
            StateInfo state = m_States[i];

            //Skip deleted states
            if (state == null)
            {
                continue;
            }

            //Update crossfade weight
            if (state.fading)
            {
                state.SetWeight(Mathf.MoveTowards(state.weight, state.targetWeight, state.fadeSpeed * deltaTime));
                if (Mathf.Approximately(state.weight, state.targetWeight))
                {
                    state.ForceWeight(state.targetWeight);
                    if (state.weight == 0f)
                    {
                        state.Stop();
                    }
                }
            }

            if (state.layerDirty >= 0)
            {
                AnimationMixerPlayable lastMixer = GetMixer(state.layerDirty);
                if (!lastMixer.Equals(AnimationMixerPlayable.Null))
                {
                    if (lastMixer.GetInput(state.indexAtLayer).Equals(state.playable))
                    {
                        graph.Disconnect(lastMixer, state.indexAtLayer);
                    }
                }

                AnimationMixerPlayable mixer = AddMixerWhenNotExist(state.layer);
                if (mixer.Equals(AnimationMixerPlayable.Null))
                {
                    throw new Exception("Can not get mixer at layer:" + state.layer);
                }

                state.indexAtLayer = m_States.GetAvailableIndexAtLayer(state.layer, state);

                int stateCountByLayer = m_States.GetCountByLayer(state.layer);
                if (stateCountByLayer > mixer.GetInputCount())
                {
                    mixer.SetInputCount(stateCountByLayer);
                }

                graph.Connect(state.playable, 0, mixer, state.indexAtLayer);
            }

            if (state.enabledDirty)
            {
                if (state.enabled)
                {
                    state.Play();
                }
                else
                {
                    state.Pause();
                }

                if (!keepStoppedPlayablesConnected)
                {
                    AnimationMixerPlayable mixer = GetMixer(state.layer);
                    if (mixer.Equals(AnimationMixerPlayable.Null))
                    {
                        throw new Exception("Can not get mixer at layer:" + state.layer);
                    }
                    Playable input = mixer.GetInput(state.indexAtLayer);
                    //if state is disabled but the corresponding input is connected, disconnect it
                    if (input.IsValid() && !state.enabled)
                    {
                        DisconnectInput(i);
                    }
                    else if (state.enabled && !input.IsValid())
                    {
                        ConnectInput(state.index);
                    }
                }
            }

            if (state.enabled && state.wrapMode == WrapMode.Once)
            {
                bool  stateIsDone = state.isDone;
                float speed       = state.speed;
                float time        = state.GetTime();
                float duration    = state.playableDuration;

                stateIsDone |= speed < 0f && time < 0f;
                stateIsDone |= speed >= 0f && time >= duration;
                if (stateIsDone)
                {
                    state.Stop();
                    state.Disable();
                    if (!keepStoppedPlayablesConnected)
                    {
                        DisconnectInput(state.index);
                    }
                }
            }

            if (!totalWeights.ContainsKey(state.layer))
            {
                totalWeights.Add(state.layer, 0.0f);
            }
            if (!mustUpdateWeights.ContainsKey(state.layer))
            {
                mustUpdateWeights.Add(state.layer, false);
            }
            totalWeights[state.layer] += state.weight;
            if (state.weightDirty)
            {
                mustUpdateWeights[state.layer] = true;
            }
            state.ResetDirtyFlags();
        }

        var e = mustUpdateWeights.GetEnumerator();

        while (e.MoveNext())
        {
            if (e.Current.Value)
            {
                float totalWeight = totalWeights[e.Current.Key];

                bool hasAnyWeight = totalWeight > 0.0f;
                for (int i = 0; i < m_States.Count; i++)
                {
                    StateInfo state = m_States[i];
                    if (state == null || state.layer != e.Current.Key)
                    {
                        continue;
                    }
                    AnimationMixerPlayable mixer = GetMixer(state.layer);
                    if (mixer.Equals(AnimationMixerPlayable.Null))
                    {
                        throw new Exception("Can not get mixer at layer:" + state.layer);
                    }

                    float weight = hasAnyWeight ? state.weight / totalWeight : 0.0f;
                    mixer.SetInputWeight(state.indexAtLayer, weight);
                }
            }
        }

        mustUpdateWeights.Clear();
        totalWeights.Clear();
    }
Пример #25
0
        //Create playable tree
        void CreateAndPlayTree()
        {
#if UNITY_2017_1_OR_NEWER
            var clipActions = actions.OfType <PlayAnimatorClip>().ToList();
            var inputCount  = 1 + clipActions.Count;
            ports         = new Dictionary <PlayAnimatorClip, int>();
            graph         = PlayableGraph.Create();
            mixerPlayable = AnimationMixerPlayable.Create(graph, inputCount, true);
            mixerPlayable.SetInputWeight(0, 1f);
            baseClipPlayable = AnimationClipPlayable.Create(graph, baseAnimationClip);
            baseClipPlayable.SetPlayState(PlayState.Paused);
            graph.Connect(baseClipPlayable, 0, mixerPlayable, 0);

            var index = 1;             //0 is baseclip
            foreach (var playAnimClip in clipActions)
            {
                var clipPlayable = AnimationClipPlayable.Create(graph, playAnimClip.animationClip);
                graph.Connect(clipPlayable, 0, mixerPlayable, index);
                mixerPlayable.SetInputWeight(index, 0f);
                ports[playAnimClip] = index;
                clipPlayable.SetPlayState(PlayState.Paused);
                index++;
            }

            animationOutput = AnimationPlayableOutput.Create(graph, "Animation", animator);
            animationOutput.SetSourcePlayable(mixerPlayable);
            mixerPlayable.SetPlayState(PlayState.Paused);
            graph.Play();
#elif UNITY_5_6_OR_NEWER
            var clipActions = actions.OfType <PlayAnimatorClip>().ToList();
            var inputCount  = 1 + clipActions.Count;
            ports = new Dictionary <PlayAnimatorClip, int>();
            graph = PlayableGraph.CreateGraph();
            mixerPlayableHandle = graph.CreateAnimationMixerPlayable(inputCount, true);
            mixerPlayableHandle.SetInputWeight(0, 1f);
            baseClipPlayableHandle           = graph.CreateAnimationClipPlayable(baseAnimationClip);
            baseClipPlayableHandle.playState = PlayState.Paused;
            graph.Connect(baseClipPlayableHandle, 0, mixerPlayableHandle, 0);

            var index = 1;             //0 is baseclip
            foreach (var playAnimClip in clipActions)
            {
                var clipPlayableHandle = graph.CreateAnimationClipPlayable(playAnimClip.animationClip);
                graph.Connect(clipPlayableHandle, 0, mixerPlayableHandle, index);
                mixerPlayableHandle.SetInputWeight(index, 0f);
                ports[playAnimClip]          = index;
                clipPlayableHandle.playState = PlayState.Paused;
                index++;
            }

            animationOutput = graph.CreateAnimationOutput("Animation", animator);
            animationOutput.sourcePlayable = mixerPlayableHandle;
            mixerPlayableHandle.playState  = PlayState.Paused;
            graph.Play();
#else
            ports         = new Dictionary <PlayAnimatorClip, int>();
            mixerPlayable = AnimationMixerPlayable.Create();

            var basePlayableClip = AnimationClipPlayable.Create(baseAnimationClip);
            basePlayableClip.state = PlayState.Paused;
            mixerPlayable.AddInput(basePlayableClip);

            foreach (var playAnimClip in actions.OfType <PlayAnimatorClip>())
            {
                var playableClip = AnimationClipPlayable.Create(playAnimClip.animationClip);
                playableClip.state = PlayState.Paused;
                var index = mixerPlayable.AddInput(playableClip);
                mixerPlayable.SetInputWeight(index, 0f);
                ports[playAnimClip] = index;
            }

            animator.SetTimeUpdateMode(DirectorUpdateMode.Manual);
            animator.Play(mixerPlayable);
            mixerPlayable.state = PlayState.Paused;
#endif

            // GraphVisualizerClient.Show(graph, animator.name);
        }
 public override void OnCreate(SequenceBehaviour sequence, IReadOnlyList <Blackboard> blackboards)
 {
     m_Mixer = ((PlayableSequence)sequence).ChildMixer;
 }
Пример #27
0
        public void InitializeSelf(PlayableGraph graph)
        {
            containingGraph = graph;
            if (states.Count == 0)
            {
                stateMixer = AnimationMixerPlayable.Create(graph, 0, false);
                return;
            }

            foreach (var transition in transitions)
            {
                transition.FetchStates(states);
            }

            runtimePlayables = new Playable[states.Count];

            stateMixer = AnimationMixerPlayable.Create(graph, states.Count, false);
            stateMixer.SetInputWeight(0, 1f);
            currentPlayedState = 0;

            // Add the statess to the graph
            for (int i = 0; i < states.Count; i++)
            {
                var state = states[i];
                stateNameToIdx[state.Name] = i;

                var playable = state.GeneratePlayable(graph, varTo1DBlendControllers, varTo2DBlendControllers, blendVars);
                runtimePlayables[i] = playable;
                graph.Connect(playable, 0, stateMixer, i);
            }

            activeWhenBlendStarted = new List <bool>();
            valueWhenBlendStarted  = new List <float>();
            for (int i = 0; i < states.Count; i++)
            {
                activeWhenBlendStarted.Add(false);
                valueWhenBlendStarted.Add(0f);
            }

            transitionLookup = new int[states.Count, states.Count];
            for (int i = 0; i < states.Count; i++)
            {
                for (int j = 0; j < states.Count; j++)
                {
                    transitionLookup[i, j] = -1;
                }
            }

            for (var i = 0; i < transitions.Count; i++)
            {
                var transition = transitions[i];
                var fromState  = states.IndexOf(transition.FromState);
                var toState    = states.IndexOf(transition.ToState);
                if (fromState == -1 || toState == -1)
                {
                    //TODO: fixme
                }
                else
                {
                    if (transitionLookup[fromState, toState] != -1)
                    {
                        Debug.LogWarning("Found two transitions from " + states[fromState] + " to " + states[toState]);
                    }

                    transitionLookup[fromState, toState] = i;
                }
            }
        }
Пример #28
0
        public Instance(EntityManager entityManager, Entity owner, PlayableGraph graph, AnimGraph_StateSelector settings)
        {
            m_settings      = settings;
            m_graph         = graph;
            m_EntityManager = entityManager;
            m_Owner         = owner;

            animStateMixer = AnimationMixerPlayable.Create(m_graph, 0, true);
            m_RootPlayable = animStateMixer;

            // Animation states
            animStates = new AnimationControllerEntry[(int)CharacterAnimationState.NumStates];

            // Instantiate controllers. We only create one of each type even though it might be used in multiple animation states
            var controllers          = new Dictionary <AnimGraphAsset, IAnimGraphInstance>();
            var controllerPorts      = new Dictionary <IAnimGraphInstance, int>();
            var stateTransitionPorts = new List <int>();
            var transitionTimes      = new Dictionary <IAnimGraphInstance, float[]>();

            foreach (var controllderDef in m_settings.controllers)
            {
                if (controllderDef.template == null)
                {
                    continue;
                }

                if (controllers.ContainsKey(controllderDef.template))
                {
                    continue;
                }

                var controller = controllderDef.template.Instatiate(entityManager, owner, m_graph);
                controllers.Add(controllderDef.template, controller);

                var outputPlayable = Playable.Null;
                var outputPort     = 0;
                controller.GetPlayableOutput(0, ref outputPlayable, ref outputPort);
                var port = animStateMixer.AddInput(outputPlayable, outputPort);

                controllerPorts.Add(controller, port);
                stateTransitionPorts.Add(port);

                var times = new float[(int)CharacterAnimationState.NumStates];
                for (var i = 0; i < (int)CharacterAnimationState.NumStates; i++)
                {
                    times[i] = controllderDef.transitionTime;
                }

                for (var i = 0; i < controllderDef.customTransitions.Length; i++)
                {
                    var sourceStateIndex = (int)controllderDef.customTransitions[i].sourceState;
                    var time             = controllderDef.customTransitions[i].transtionTime;
                    times[sourceStateIndex] = time;
                }

                transitionTimes.Add(controller, times);
            }

            // Setup states specifically defined
            foreach (var controllderDef in m_settings.controllers)
            {
                var animState = controllderDef.animationState;
                if (animStates[(int)animState].controller != null)
                {
                    GameDebug.LogWarning("Animation state already registered");
                    continue;
                }

                var controller = controllers[controllderDef.template];
                animStates[(int)animState].controller       = controller;
                animStates[(int)animState].animStateUpdater = controller as IGraphState;
                animStates[(int)animState].port             = controllerPorts[controller];
                animStates[(int)animState].transitionTimes  = transitionTimes[controller];
            }

            m_StateTranstion = new SimpleTranstion <AnimationMixerPlayable>(animStateMixer, stateTransitionPorts.ToArray());
        }
Пример #29
0
 /// <summary>
 /// 初期化Playableに必要な物の作成
 /// </summary>
 public void Initialize(int maxBlendNum = 2)
 {
     playableGraph = PlayableGraph.Create();
     mixer         = AnimationMixerPlayable.Create(playableGraph, maxBlendNum, true);
 }
Пример #30
0
 protected override void CreateMixerPlayable()
 {
     mMixerPlayable = AnimationMixerPlayable.Create(mGraph, 1, true);
 }