/// <summary>
        /// Synchronize time with defined layer. Returns false if the time is not synchronized.
        /// </summary>
        private bool ProcessLayerTimeSync(ref MyAnimationUpdateData data)
        {
            if (m_synchronizeWithLayerRef == null)
            {
                if (m_synchronizeWithLayerName == null)
                {
                    return(false);
                }

                m_synchronizeWithLayerRef = data.Controller.GetLayerByName(m_synchronizeWithLayerName);
                if (m_synchronizeWithLayerRef == null)
                {
                    return(false);
                }
            }
            var nodeFromSyncLayer = m_synchronizeWithLayerRef.CurrentNode as MyAnimationStateMachineNode;

            if (nodeFromSyncLayer == null || nodeFromSyncLayer.RootAnimationNode == null)
            {
                return(false);
            }

            SetLocalTimeNormalized(nodeFromSyncLayer.RootAnimationNode.GetLocalTimeNormalized());
            return(true);
        }
        public override void OnUpdate(MyStateMachine stateMachine)
        {
            MyAnimationStateMachine animStateMachine = stateMachine as MyAnimationStateMachine;

            if (animStateMachine == null)
            {
                Debug.Fail("Animation machine nodes must be inside animation state machine.");
                return;
            }
            if (m_rootAnimationNode != null)
            {
                animStateMachine.CurrentUpdateData.AddVisitedTreeNodesPathPoint(1);
                m_rootAnimationNode.Update(ref animStateMachine.CurrentUpdateData);
            }
            else
            {
                animStateMachine.CurrentUpdateData.BonesResult =
                    animStateMachine.CurrentUpdateData.Controller.ResultBonesPool.Alloc();
            }
            animStateMachine.CurrentUpdateData.AddVisitedTreeNodesPathPoint(0);
        }
Example #3
0
        /// <summary>
        /// Create animation layer with unique name. Parameter insertionIndex can be left -1 to add the layer at the end.
        /// If layer with same name is already present, method fails and returns null.
        /// </summary>
        public MyAnimationStateMachine CreateLayer(string name, int insertionIndex = -1)
        {
            if (GetLayerByName(name) != null)
            {
                Debug.Fail("Cannot create layer: layer with name '" + name + "' already exists.");
                return(null);
            }

            MyAnimationStateMachine newLayer = new MyAnimationStateMachine();

            newLayer.Name = name;
            if (insertionIndex != -1)
            {
                m_tableLayerNameToIndex.Add(name, insertionIndex);
                m_layers.Insert(insertionIndex, newLayer);
            }
            else
            {
                m_tableLayerNameToIndex.Add(name, m_layers.Count);
                m_layers.Add(newLayer);
            }

            return(newLayer);
        }
        /// <summary>
        /// Create animation layer with unique name. Parameter insertionIndex can be left -1 to add the layer at the end.
        /// If layer with same name is already present, method fails and returns null.
        /// </summary>
        public MyAnimationStateMachine CreateLayer(string name, int insertionIndex = -1)
        {
            if (GetLayerByName(name) != null)
            {
                Debug.Fail("Cannot create layer: layer with name '" + name + "' already exists.");
                return null;
            }

            MyAnimationStateMachine newLayer = new MyAnimationStateMachine();
            newLayer.Name = name;
            if (insertionIndex != -1)
            {
                m_tableLayerNameToIndex.Add(name, insertionIndex);
                m_layers.Insert(insertionIndex, newLayer);
            }
            else
            {
                m_tableLayerNameToIndex.Add(name, m_layers.Count);
                m_layers.Add(newLayer);
            }

            return newLayer;
        }
        // Initialize state machine of one layer.
        private static bool InitLayerNodes(MyAnimationStateMachine layer, string stateMachineName, MyAnimationControllerDefinition animControllerDefinition,
            MyAnimationController animationController, string currentNodeNamePrefix, MyAnimationVirtualNodes virtualNodes, bool forceReloadMwm)
        {
            var objBuilderStateMachine = animControllerDefinition.StateMachines.FirstOrDefault(x => x.Name == stateMachineName);
            if (objBuilderStateMachine == null)
            {
                Debug.Fail("Animation state machine " + stateMachineName + " was not found.");
                return false;
            }

            bool result = true;
            // 1st step: generate nodes
            if (objBuilderStateMachine.Nodes != null)
            foreach (var objBuilderNode in objBuilderStateMachine.Nodes)
            {
                string absoluteNodeName = currentNodeNamePrefix + objBuilderNode.Name;
                if (objBuilderNode.StateMachineName != null)
                {
                    // embedded state machine, copy its nodes
                    if (!InitLayerNodes(layer, objBuilderNode.StateMachineName, animControllerDefinition, animationController, absoluteNodeName + "/", virtualNodes, forceReloadMwm))
                        result = false;
                }
                else
                {
                    var smNode = new VRageRender.Animations.MyAnimationStateMachineNode(absoluteNodeName);
                    if (objBuilderNode.Type == MyObjectBuilder_AnimationSMNode.MySMNodeType.PassThrough
                        || objBuilderNode.Type == MyObjectBuilder_AnimationSMNode.MySMNodeType.Any
                        || objBuilderNode.Type == MyObjectBuilder_AnimationSMNode.MySMNodeType.AnyExceptTarget)
                    {
                        smNode.PassThrough = true;
                    }
                    else
                    {
                        smNode.PassThrough = false;
                    }

                    if (objBuilderNode.Type == MyObjectBuilder_AnimationSMNode.MySMNodeType.Any
                        || objBuilderNode.Type == MyObjectBuilder_AnimationSMNode.MySMNodeType.AnyExceptTarget)
                    {
                        virtualNodes.NodesAny.Add(absoluteNodeName, new MyAnimationVirtualNodeData()
                        {
                            AnyNodePrefix = currentNodeNamePrefix,
                            ExceptTarget = (objBuilderNode.Type == MyObjectBuilder_AnimationSMNode.MySMNodeType.AnyExceptTarget)
                        });
                    }

                    layer.AddNode(smNode);

                    if (objBuilderNode.AnimationTree != null)
                    {
                        var smNodeAnimTree = InitNodeAnimationTree(objBuilderNode.AnimationTree.Child, forceReloadMwm);
                        smNode.RootAnimationNode = smNodeAnimTree;
                    }
                    else
                    {
                        smNode.RootAnimationNode = new MyAnimationTreeNodeDummy();
                    }
                }
            }

            // 2nd step: generate transitions
            if (objBuilderStateMachine.Transitions != null)
            foreach (var objBuilderTransition in objBuilderStateMachine.Transitions)
            {
                string absoluteNameNodeFrom = currentNodeNamePrefix + objBuilderTransition.From;
                string absoluteNameNodeTo = currentNodeNamePrefix + objBuilderTransition.To;

                MyAnimationVirtualNodeData virtualNodeData;
                if (virtualNodes.NodesAny.TryGetValue(absoluteNameNodeFrom, out virtualNodeData))
                {
                    // nodes of type "any":
                    // "any" node is source: we create transitions directly from all nodes
                    // "any" node is target: we will use "any" node as pass through
                    foreach (var nodeFromCandidate in layer.AllNodes)
                    {
                        if (nodeFromCandidate.Key.StartsWith(virtualNodeData.AnyNodePrefix) // select nodes in the same SM
                            && nodeFromCandidate.Key != absoluteNameNodeFrom)    // disallow from "any" to the same "any"
                        {
                            // create transition if target is different from source or when we don't care about it
                            if (!virtualNodeData.ExceptTarget || absoluteNameNodeTo != nodeFromCandidate.Key)
                                CreateTransition(layer, animationController, nodeFromCandidate.Key, absoluteNameNodeTo, objBuilderTransition);
                        }
                    }
                }

                CreateTransition(layer, animationController, absoluteNameNodeFrom, absoluteNameNodeTo, objBuilderTransition);
            }

            return result;
        }
 private static void CreateTransition(MyAnimationStateMachine layer, MyAnimationController animationController,
     string absoluteNameNodeFrom, string absoluteNameNodeTo, MyObjectBuilder_AnimationSMTransition objBuilderTransition)
 {
     int conditionConjunctionIndex = 0;
     do
     {
         // generate transition for each condition conjunction
         var transition = layer.AddTransition(absoluteNameNodeFrom, absoluteNameNodeTo,
             new VRageRender.Animations.MyAnimationStateMachineTransition()) as
             VRageRender.Animations.MyAnimationStateMachineTransition;
         // if ok, fill in conditions
         if (transition != null)
         {
             transition.Name =
                 MyStringId.GetOrCompute(objBuilderTransition.Name != null ? objBuilderTransition.Name.ToLower() : null);
             transition.TransitionTimeInSec = objBuilderTransition.TimeInSec;
             transition.Sync = objBuilderTransition.Sync;
             transition.Priority = objBuilderTransition.Priority;
             if (objBuilderTransition.Conditions != null &&
                 objBuilderTransition.Conditions[conditionConjunctionIndex] != null)
             {
                 var conjunctionOfConditions =
                     objBuilderTransition.Conditions[conditionConjunctionIndex].Conditions;
                 foreach (var objBuilderCondition in conjunctionOfConditions)
                 {
                     var condition = ParseOneCondition(animationController, objBuilderCondition);
                     if (condition != null)
                         transition.Conditions.Add(condition);
                 }
             }
         }
         conditionConjunctionIndex++;
     } while (objBuilderTransition.Conditions != null &&
              conditionConjunctionIndex < objBuilderTransition.Conditions.Length);
 }
        /// <summary>
        /// Synchronize time with defined layer. Returns false if the time is not synchronized.
        /// </summary>
        private bool ProcessLayerTimeSync(ref MyAnimationUpdateData data)
        {
            if (m_synchronizeWithLayerRef == null)
            {
                if (m_synchronizeWithLayerName == null)
                {
                    return false;
                }
                
                m_synchronizeWithLayerRef = data.Controller.GetLayerByName(m_synchronizeWithLayerName);
                if (m_synchronizeWithLayerRef == null)
                    return false;
            }
            var nodeFromSyncLayer = m_synchronizeWithLayerRef.CurrentNode as MyAnimationStateMachineNode;
            if (nodeFromSyncLayer == null || nodeFromSyncLayer.RootAnimationNode == null)
                return false;

            SetLocalTimeNormalized(nodeFromSyncLayer.RootAnimationNode.GetLocalTimeNormalized());
            return true;
        }