// Initialize this animation controller from given object builder.
        // param forceReloadMwm: (Re)load MWM files even if they are in cache.
        // Returns true on success.
        public static bool InitFromDefinition(this VRage.Game.Components.MyAnimationControllerComponent thisController,
            MyAnimationControllerDefinition animControllerDefinition, bool forceReloadMwm = false)
        {
            bool result = true;
            thisController.Clear();

            thisController.SourceId = animControllerDefinition.Id;
            
            foreach (var objBuilderLayer in animControllerDefinition.Layers)
            {
                var layer = thisController.Controller.CreateLayer(objBuilderLayer.Name);
                if (layer == null)
                {
                    continue;
                }
                switch (objBuilderLayer.Mode)
                {
                    case VRage.Game.ObjectBuilders.MyObjectBuilder_AnimationLayer.MyLayerMode.Add:
                        layer.Mode = VRageRender.Animations.MyAnimationStateMachine.MyBlendingMode.Add;
                        break;
                    case VRage.Game.ObjectBuilders.MyObjectBuilder_AnimationLayer.MyLayerMode.Replace:
                        layer.Mode = VRageRender.Animations.MyAnimationStateMachine.MyBlendingMode.Replace;
                        break;
                    default:
                        Debug.Fail("Unknown layer mode.");
                        layer.Mode = VRageRender.Animations.MyAnimationStateMachine.MyBlendingMode.Replace;
                        break;
                }
                if (objBuilderLayer.BoneMask != null)
                {
                    string[] boneMaskArray = objBuilderLayer.BoneMask.Split(m_boneListSeparators);
                    foreach (string s in boneMaskArray)
                        layer.BoneMaskStrIds.Add(MyStringId.GetOrCompute(s));
                }
                else
                {
                    layer.BoneMaskStrIds.Clear();
                }
                layer.BoneMask = null; // this will build itself in animation controller when we know all character bones
                MyAnimationVirtualNodes virtualNodes = new MyAnimationVirtualNodes();
                result = InitLayerNodes(layer, objBuilderLayer.StateMachine, animControllerDefinition, thisController.Controller, layer.Name + "/",
                    virtualNodes, forceReloadMwm) && result;
                layer.SetState(layer.Name + "/" + objBuilderLayer.InitialSMNode);
                layer.SortTransitions();
            }

            foreach (var footIkChain in animControllerDefinition.FootIkChains)
                thisController.InverseKinematics.RegisterFootBone(footIkChain.FootBone, footIkChain.ChainLength, footIkChain.AlignBoneWithTerrain);
            foreach (var ignoredBone in animControllerDefinition.IkIgnoredBones)
                thisController.InverseKinematics.RegisterIgnoredBone(ignoredBone);

            if (result)
                thisController.MarkAsValid();
            return result;
        }
示例#2
0
        // Initialize this animation controller from given object builder.
        // Returns true on success.
        public static bool InitFromDefinition(this VRage.Game.Components.MyAnimationControllerComponent thisController,
                                              MyAnimationControllerDefinition animControllerDefinition)
        {
            bool result = true;

            thisController.Clear();

            thisController.SourceId = animControllerDefinition.Id;

            foreach (var objBuilderLayer in animControllerDefinition.Layers)
            {
                var layer = thisController.Controller.CreateLayer(objBuilderLayer.Name);
                if (layer == null)
                {
                    continue;
                }
                switch (objBuilderLayer.Mode)
                {
                case VRage.Game.ObjectBuilders.MyObjectBuilder_AnimationLayer.MyLayerMode.Add:
                    layer.Mode = VRage.Animations.MyAnimationStateMachine.MyBlendingMode.Add;
                    break;

                case VRage.Game.ObjectBuilders.MyObjectBuilder_AnimationLayer.MyLayerMode.Replace:
                    layer.Mode = VRage.Animations.MyAnimationStateMachine.MyBlendingMode.Replace;
                    break;

                default:
                    Debug.Fail("Unknown layer mode.");
                    layer.Mode = VRage.Animations.MyAnimationStateMachine.MyBlendingMode.Replace;
                    break;
                }
                if (objBuilderLayer.BoneMask != null)
                {
                    string[] boneMaskArray = objBuilderLayer.BoneMask.Split(m_boneListSeparators);
                    foreach (string s in boneMaskArray)
                    {
                        layer.BoneMaskStrIds.Add(MyStringId.GetOrCompute(s));
                    }
                }
                else
                {
                    layer.BoneMaskStrIds.Clear();
                }
                layer.BoneMask = null; // this will build itself in animation controller when we know all character bones
                MyAnimationVirtualNodes virtualNodes = new MyAnimationVirtualNodes();
                result = InitLayerNodes(layer, objBuilderLayer.StateMachine, animControllerDefinition, thisController.Controller, layer.Name + "/", virtualNodes) && result;
                layer.SetState(layer.Name + "/" + objBuilderLayer.InitialSMNode);
                layer.SortTransitions();
            }
            if (result)
            {
                thisController.MarkAsValid();
            }
            return(result);
        }
        // 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;
        }
示例#4
0
        // Initialize state machine of one layer.
        private static bool InitLayerNodes(MyAnimationStateMachine layer, string stateMachineName, MyAnimationControllerDefinition animControllerDefinition,
                                           MyAnimationController animationController, string currentNodeNamePrefix, MyAnimationVirtualNodes virtualNodes)
        {
            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))
                        {
                            result = false;
                        }
                    }
                    else
                    {
                        var smNode = new VRage.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);
                            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);
        }