//Create and play the playable graph
        void CreateAndPlayTree()
        {
            graph           = PlayableGraph.Create();
            animationOutput = AnimationPlayableOutput.Create(graph, "Animation", animator);
            masterMixer     = AnimationLayerMixerPlayable.Create(graph, siblingTracks.Count + 2);
            for (var i = 0; i < siblingTracks.Count; i++)
            {
                var animatorTrack = siblingTracks[i];
                var mix           = animatorTrack.CreateClipsMixer(graph);
                graph.Connect(mix, 0, masterMixer, i);
                masterMixer.SetInputWeight(i, 1f);
                if (animatorTrack.mask != null)
                {
                    masterMixer.SetLayerMaskFromAvatarMask((uint)i, animatorTrack.mask);
                }
                masterMixer.SetLayerAdditive((uint)i, animatorTrack.blendMode == AnimationBlendMode.Additive);
            }

            animatorPlayable = AnimatorControllerPlayable.Create(graph, animator.runtimeAnimatorController);
            graph.Connect(animatorPlayable, 0, masterMixer, siblingTracks.Count + 1);
            masterMixer.SetInputWeight(siblingTracks.Count + 1, 0f);

            animationOutput.SetSourcePlayable(masterMixer);

            // graph.Play();
            // masterMixer.Pause();

            // GraphVisualizerClient.Show(graph, this.name);
        }
Esempio n. 2
0
        //============================================================================================
        /**
        *  @brief Constructor for the MxMLayer class which takes a playable instead of an animation clip. 
        *  Sets up all initial values and creates the layer's mixer.
        *  
        *  @param [int] a_id - the layer id (lowest layer value is 2 for MxMLayers)
        *  @param [int] a_maxClips - the maximum number of clips that can be blended on this layer
        *  @param [ref PlayableGraph] a_playableGraph - the playable graph that this layer lives on
        *  @param [Playable] a_playable - the playable to use for this layer
        *  @param [AvatarMask] a_mask - the mask to use with this player (Default null)
        *  @param [float] a_weight - the starting weight of this layer (Default 0)
        *  @param [bool] a_additive - whether the layer is additive or not (Default false)
        *         
        *********************************************************************************************/
        public MxMLayer(int a_id, ref AnimationLayerMixerPlayable a_layerMixer,
           Playable a_playable, AvatarMask a_mask = null, float a_weight = 0f, bool a_additive = false)
        {
            if (!a_playable.IsValid())
                Debug.LogError("Error: Attempting to create an MxMLayer with an invalid playable");

            if (!a_layerMixer.IsValid())
                Debug.LogError("Error: Attempting to create an MxMLayer with an invalid layerMixer.");

            m_layerMixer = a_layerMixer;
            m_playableGraph = m_layerMixer.GetGraph();

            Id = a_id;

            PrimaryInputId = 0;
            MaxClips = 1;

            m_layerMixer.ConnectInput(Id, a_playable, 0);

            Mask = a_mask;

            m_layerMixer.SetLayerAdditive((uint)Id, a_additive);
            m_layerMixer.SetInputWeight(Id, Mathf.Clamp01(a_weight));

            SubLayerWeights = new float[1];
            SubLayerWeights[0] = 1f;
        }
Esempio n. 3
0
        private void Play(AnimationClip animClip)
        {
            m_Graph = PlayableGraph.Create(name + " Character Anims");
            m_Graph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);

            // Create the starting animation clip.
            AnimationClipPlayable animPlayable = AnimationClipPlayable.Create(m_Graph, animClip);

            // Create the transition mixer for changing animations over time.
            AnimationMixerPlayable transitionMixer = AnimationMixerPlayable.Create(m_Graph, 2);

            // Connect the base clip to the transition mixer.
            m_Graph.Connect(animPlayable, 0, transitionMixer, 1);

            transitionMixer.SetInputWeight(0, 0);
            transitionMixer.SetInputWeight(1, 1);

            // Create the layer output to handle 'heels'/'barefoot' options.
            AnimationPlayableOutput     playableOutput = AnimationPlayableOutput.Create(m_Graph, "LayerMixer", m_Animator);
            AnimationLayerMixerPlayable layerMixer     = AnimationLayerMixerPlayable.Create(m_Graph, 2);

            // Set the 'heels' layer to additive.
            layerMixer.SetLayerAdditive(1, true);
            playableOutput.SetSourcePlayable(layerMixer);

            layerMixer.ConnectInput(0, transitionMixer, 0, 1);

            m_Graph.Play();
        }
    public ActionAnimationHandler(AnimationLayerMixerPlayable mixer, ActionAnimationDefinition[] actionAnimationDefs)
    {
        if (actionAnimationDefs == null)
        {
            return;
        }

        m_mixer = mixer;
        foreach (var def in actionAnimationDefs)
        {
            if (def.animation == null)
            {
                continue;
            }

            if (m_actionAnimations.ContainsKey(def.action))
            {
                continue;
            }

            ActionAnimation actionAnim = new ActionAnimation();
            actionAnim.animation = AnimationClipPlayable.Create(mixer.GetGraph(), def.animation);
            actionAnim.animation.SetApplyFootIK(false);
            actionAnim.animation.SetDuration(def.animation.length);
            actionAnim.port = mixer.AddInput(actionAnim.animation, 0);
            actionAnim.restartTimeOffset = def.restartTimeOffset;
            mixer.SetLayerAdditive((uint)actionAnim.port, true);
            m_actionAnimations.Add(def.action, actionAnim);
        }
    }
Esempio n. 5
0
            public Instance(AnimStateController controller, PlayableGraph graph, AnimGraphStand settings)
            {
                m_Settings       = settings;
                m_AnimState      = controller.GetComponent <AnimStateData>();
                m_PredictedState = controller.GetComponent <LogicStateData>();

                m_Mask = 1 << LayerMask.NameToLayer("Default") | 1 << LayerMask.NameToLayer("Platform");

                m_LocomotionMixer = AnimationMixerPlayable.Create(graph, (int)LocoMixerPort.Count);

                m_AnimIdle = AnimationClipPlayable.Create(graph, settings.animIdle);
                graph.Connect(m_AnimIdle, 0, m_LocomotionMixer, (int)LocoMixerPort.Idle);
                m_LocomotionMixer.SetInputWeight((int)LocoMixerPort.Idle, 1.0f);

                m_AnimTurnL = CreateTurnPlayable(graph, settings.animTurnL, m_LocomotionMixer, LocoMixerPort.TurnL);
                m_AnimTurnR = CreateTurnPlayable(graph, settings.animTurnR, m_LocomotionMixer, LocoMixerPort.TurnR);

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

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

                if (settings.animTurnL.events.Length != 0)
                {
                    m_LeftTurnFootFalls  = ExtractFootFalls(settings.animTurnL);
                    m_RightTurnFootFalls = ExtractFootFalls(settings.animTurnR);
                }

                var animator  = controller.GetComponent <Animator>();
                var skeleton  = controller.GetComponent <Skeleton>();
                var leftToes  = skeleton.bones[skeleton.GetBoneIndex(settings.leftToeBone.GetHashCode())];
                var rightToes = skeleton.bones[skeleton.GetBoneIndex(settings.rightToeBone.GetHashCode())];

                var ikJob = new FootIkJob
                {
                    settings = settings.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_AimMixer = AnimationMixerPlayable.Create(graph, (int)AimMixerPort.Count, true);

                m_AnimAimLeft  = CreateAimPlayable(graph, settings.animAimLeft, m_AimMixer, AimMixerPort.AimLeft);
                m_AnimAimMid   = CreateAimPlayable(graph, settings.animAimMid, m_AimMixer, AimMixerPort.AimMid);
                m_AnimAimRight = CreateAimPlayable(graph, settings.animAimRight, m_AimMixer, AimMixerPort.AimRight);

                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);
            }
Esempio n. 6
0
        //============================================================================================
        /**
        *  @brief Constructor for the MxMLayer class. Sets up all initial values and creates the layer's
        *  mixer 
        *  
        *  @param [int] a_id - the layer id (lowest layer value is 2 for MxMLayers)
        *  @param [int] a_maxClips - the maximum number of clips that can be blended on this layer
        *  @param [ref PlayableGraph] a_playableGraph - the playable graph that this layer lives on
        *  @param [AnimationClip] a_clip - the starting animation clip to use for this layer.
        *  @param [AvatarMask] a_mask - the mask to use with this player (Default null)
        *  @param [float] a_weight - the starting weight of this layer (Default 0)
        *  @param [bool] a_additive - whether the layer is additive or not (Default false)
        *         
        *********************************************************************************************/
        public MxMLayer(int a_id, int a_maxClips, ref AnimationLayerMixerPlayable a_layerMixer, 
            AnimationClip a_clip, AvatarMask a_mask = null, float a_weight = 0f, bool a_additive = false)
        {
            Assert.IsNotNull(a_clip, "Error: Attempting to create an MxMLayer with null AnimationClip");

            if (!a_layerMixer.IsValid())
                Debug.LogError("Error: Attempting to create an MxMLayer with an invalid layerMixer.");

            m_playableGraph = a_layerMixer.GetGraph();
            m_layerMixer = a_layerMixer;
            PrimaryClip = a_clip;

            Id = a_id;
            MaxClips = a_maxClips;

            PrimaryInputId = 0;

            Mixer = AnimationMixerPlayable.Create(m_playableGraph, a_maxClips, true);
            var clipPlayable = AnimationClipPlayable.Create(m_playableGraph, PrimaryClip);

            m_layerMixer.ConnectInput(Id, Mixer, 0);

            Mixer.ConnectInput(0, clipPlayable, 0);
            Mixer.SetInputWeight(0, 1f);

            Mask = a_mask;

            m_layerMixer.SetLayerAdditive((uint)Id, a_additive);
            m_layerMixer.SetInputWeight(Id, Mathf.Clamp01(a_weight));

            SubLayerWeights = new float[MaxClips];
            SubLayerWeights[0] = 1f;
        }
Esempio n. 7
0
            public Instance(AnimStateController controller, PlayableGraph graph, AnimGraphJump settings)
            {
                m_AnimState = controller.GetComponent <AnimStateData>();

                m_Mixer = AnimationLayerMixerPlayable.Create(graph, 2);

                m_AnimJump = AnimationClipPlayable.Create(graph, settings.animJump);
                m_AnimJump.SetApplyFootIK(true);
                m_AnimJump.SetDuration(settings.animJump.length);
                m_AnimJump.Pause();
                graph.Connect(m_AnimJump, 0, m_Mixer, 0);
                m_Mixer.SetInputWeight(0, 1);

                var gameJumpHeight   = 1.0f;
                var gameJumpDuration = 0.3f;
                var animJumpVel      = settings.jumpHeight / settings.animJump.length;
                var characterJumpVel = gameJumpHeight / gameJumpDuration;

                m_PlaySpeed = characterJumpVel / animJumpVel;

                m_AnimAim = AnimationClipPlayable.Create(graph, settings.animAim);
                m_AnimAim.SetApplyFootIK(false);
                m_AnimAim.Pause();
                graph.Connect(m_AnimAim, 0, m_Mixer, 1);
                m_Mixer.SetInputWeight(1, 1);
                m_Mixer.SetLayerAdditive(1, true);

                m_AimTimeFactor = settings.animAim.length / 180.0f;
            }
Esempio n. 8
0
        /// <summary>
        /// Set layer blend type is additive.
        /// </summary>
        /// <param name="layerIndex">layer index.</param>
        /// <param name="isAdditive">Blend type is additive.</param>
        public void SetLayerAdditive(int layerIndex, bool isAdditive)
        {
            // Fail silently...
            if (layerIndex <= 0 || layerIndex >= LayerCount)
            {
                return;
            }

            _layerMixer.SetLayerAdditive((uint)layerIndex, isAdditive);
        }
        public void InitializeLayerBlending(PlayableGraph graph, int layerIndex, AnimationLayerMixerPlayable layerMixer)
        {
            graph.Connect(stateMixer, 0, layerMixer, layerIndex);

            layerMixer.SetInputWeight(layerIndex, startWeight);
            layerMixer.SetLayerAdditive((uint)layerIndex, type == AnimationLayerType.Additive);
            if (mask != null)
            {
                layerMixer.SetLayerMaskFromAvatarMask((uint)layerIndex, mask);
            }
        }
Esempio n. 10
0
    public AimVerticalHandler(AnimationLayerMixerPlayable mixer, AnimationClip animAimDownToUp)
    {
        // Aim
        m_animAim = AnimationClipPlayable.Create(mixer.GetGraph(), animAimDownToUp);
        m_animAim.SetApplyFootIK(false);
        m_animAim.Pause();
        m_aimTimeFactor = animAimDownToUp.length / 180.0f;

        m_port = mixer.AddInput(m_animAim, 0);
        mixer.SetLayerAdditive((uint)m_port, true);
        mixer.SetInputWeight(m_port, 1.0f);
    }
Esempio n. 11
0
        public void InitializeLayerBlending(PlayableGraph graph, int layerIndex, AnimationLayerMixerPlayable layerMixer)
        {
            graph.Connect(stateMixer, 0, layerMixer, layerIndex);

            layerMixer.SetInputWeight(layerIndex, startWeight);
            layerMixer.SetLayerAdditive((uint)layerIndex, type == AnimationLayerType.Additive);
            if (mask != null)
            {
                layerMixer.SetLayerMaskFromAvatarMask((uint)layerIndex, mask);
            }

            if (layerIndex == 0)
            {
                //Doesn't make any sense for base layer to be additive!
                layerMixer.SetLayerAdditive((uint)layerIndex, false);
            }
            else
            {
                layerMixer.SetLayerAdditive((uint)layerIndex, type == AnimationLayerType.Additive);
            }
        }
Esempio n. 12
0
    //private AnimatorController animController;

    void Start()
    {
        playableGraph = PlayableGraph.Create("ClairePlayableGraph");

        playableGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);

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

        // Create a Mixer
        AnimationLayerMixerPlayable mixerLayerPlayable = AnimationLayerMixerPlayable.Create(playableGraph, 2);


        playableOutput.SetSourcePlayable(mixerLayerPlayable);

        // Wrap the clip in a playable

        var clipPlayable = AnimationClipPlayable.Create(playableGraph, clip);

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


        // Wrap AnimController

        runtimeAnimController = GetComponent <Animator>().runtimeAnimatorController;
        //animController = (AnimatorController)animator.runtimeAnimatorController;
        var runtimeAnimControllerPlayable = AnimatorControllerPlayable.Create(playableGraph, runtimeAnimController);


        // Connect to Mixer

        playableGraph.Connect(runtimeAnimControllerPlayable, 0, mixerLayerPlayable, 1);
        playableGraph.Connect(clipPlayable, 0, mixerLayerPlayable, 0);

        mixerLayerPlayable.SetInputWeight(0, 1.0f);
        mixerLayerPlayable.SetInputWeight(1, 1.0f);

        //mixerLayerPlayable.SetLayerAdditive(0, true);
        mixerLayerPlayable.SetLayerAdditive(1, true);
        Debug.Log("Is layer 0 additive: " + mixerLayerPlayable.IsLayerAdditive(0));
        Debug.Log("Is layer 1 additive: " + mixerLayerPlayable.IsLayerAdditive(1));

        //mixerLayerPlayable.SetLayerMaskFromAvatarMask(1, headMask);

        // Connect the Playable to an output

        //playableOutput.SetSourcePlayable(clipPlayable);

        // Plays the Graph.

        playableGraph.Play();
    }
Esempio n. 13
0
            public Instance(AnimStateController controller, PlayableGraph graph, AnimGraphSquash settings)
            {
                m_Settings = settings;

                m_AnimState      = controller.GetComponent <AnimStateData>();
                m_PredictedState = controller.GetComponent <LogicStateData>();

                m_Mixer = AnimationLayerMixerPlayable.Create(graph, 2);

                m_AnimSquash = AnimationClipPlayable.Create(graph, settings.animSquash);
                m_AnimSquash.SetApplyFootIK(false);
                m_AnimSquash.SetDuration(settings.animSquash.length);
                m_AnimSquash.Pause();

                m_Mixer.ConnectInput(1, m_AnimSquash, 0, 0.0f);
                m_Mixer.SetLayerAdditive(1, true);
            }
Esempio n. 14
0
        public Finger(PlayableGraph graph, AnimationClip closed, AnimationClip opened, AvatarMask mask, VariableTweener lerper)
        {
            mixer = AnimationLayerMixerPlayable.Create(graph, 2);
            var openPlayable = AnimationClipPlayable.Create(graph, opened);

            graph.Connect(openPlayable, 0, mixer, 0);
            var closedPlayable = AnimationClipPlayable.Create(graph, closed);

            graph.Connect(closedPlayable, 0, mixer, 1);
            mixer.SetLayerAdditive(0, false);
            mixer.SetLayerMaskFromAvatarMask(0, mask);
            mixer.SetInputWeight(0, 1);
            mixer.SetInputWeight(1, 0);
            crossFadingWeight           = new TweenableFloat(lerper);
            crossFadingWeight.onChange += (value) =>
            {
                mixer.SetInputWeight(0, 1 - value);
                mixer.SetInputWeight(1, value);
            };
        }
Esempio n. 15
0
            public Instance(AnimStateController controller, PlayableGraph graph, AnimGraphInAir settings)
            {
                m_AnimState = controller.GetComponent <AnimStateData>();

                m_Mixer = AnimationLayerMixerPlayable.Create(graph, 2);

                m_AnimInAir = AnimationClipPlayable.Create(graph, settings.animInAir);
                m_AnimInAir.Play();
                m_AnimInAir.SetApplyFootIK(false);
                graph.Connect(m_AnimInAir, 0, m_Mixer, 0);
                m_Mixer.SetInputWeight(0, 1);

                m_AnimAim = AnimationClipPlayable.Create(graph, settings.animAim);
                m_AnimAim.SetApplyFootIK(false);
                m_AnimAim.Pause();
                graph.Connect(m_AnimAim, 0, m_Mixer, 1);
                m_Mixer.SetInputWeight(1, 1);
                m_Mixer.SetLayerAdditive(1, true);

                m_AimTimeFactor = settings.animAim.length / 180.0f;
            }
Esempio n. 16
0
            public Instance(AnimStateController controller, PlayableGraph graph, AnimGraphMove8Dir settings)
            {
                m_Settings  = settings;
                m_AnimState = controller.GetComponent <AnimStateData>();

                m_LocomotionMixer = AnimationLayerMixerPlayable.Create(graph, 3);

                m_BlendTree             = new BlendTree2d(graph, settings.blendSpaceNodes);
                m_BlendTree.masterSpeed = settings.animMovePlaySpeed;
                graph.Connect(m_BlendTree.rootPlayable, 0, m_LocomotionMixer, 0);
                m_LocomotionMixer.SetInputWeight(0, 1.0f);

                if (settings.animAim != null)
                {
                    m_AnimAim = AnimationClipPlayable.Create(graph, settings.animAim);
                    m_AnimAim.SetApplyFootIK(false);
                    m_AnimAim.Pause();
                    m_AimTimeFactor = m_AnimAim.GetAnimationClip().length / 180.0f;

                    graph.Connect(m_AnimAim, 0, m_LocomotionMixer, 1);
                    m_LocomotionMixer.SetInputWeight(1, 1.0f);
                    m_LocomotionMixer.SetLayerAdditive(1, true);
                }
            }
 /// <summary>[Pro-Only]
 /// Sets the layer at the specified index to blend additively with earlier layers (if true) or to override them
 /// (if false). Newly created layers will override by default.
 /// </summary>
 public void SetAdditive(int index, bool value)
 {
     SetMinCount(index + 1);
     LayerMixer.SetLayerAdditive((uint)index, value);
 }
Esempio n. 18
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;
            }
        }
Esempio n. 19
0
 public void SetLayerAdditive(uint layerIndex, bool isAdditive)
 {
     layerMixer.SetLayerAdditive(layerIndex, isAdditive);
 }