// 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;
        }
 // 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();
     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
         result = InitLayerNodes(layer, objBuilderLayer.StateMachine, animControllerDefinition, thisController.Controller) && result;
         layer.SetState(objBuilderLayer.InitialSMNode);
         // todo: bone mask
     }
     return result;
 }
Ejemplo n.º 3
0
        public override void AfterLoaded(ref Bundle definitions)
        {
            foreach (var def in definitions.Definitions)
            {
                MyAnimationControllerDefinition animationController = def.Value as MyAnimationControllerDefinition;
                if (animationController == null || animationController.StateMachines == null || def.Value.Context.IsBaseGame ||
                    def.Value.Context == null || def.Value.Context.ModPath == null)
                {
                    continue;
                }

                foreach (var sm in animationController.StateMachines)
                {
                    foreach (var node in sm.Nodes)
                    {
                        if (node.AnimationTree != null && node.AnimationTree.Child != null)
                        {
                            ResolveMwmPaths(def.Value.Context, node.AnimationTree.Child);
                        }
                    }
                }
            }
        }
        // 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;
        }
Ejemplo n.º 5
0
        public override void OverrideBy(ref Bundle currentDefinitions, ref Bundle overrideBySet)
        {
            foreach (var def in overrideBySet.Definitions)
            {
                MyAnimationControllerDefinition modifyingAnimationController = def.Value as MyAnimationControllerDefinition;
                if (def.Value.Enabled && modifyingAnimationController != null)
                {
                    bool justCopy = true;
                    if (currentDefinitions.Definitions.ContainsKey(def.Key))
                    {
                        MyAnimationControllerDefinition originalAnimationController = currentDefinitions.Definitions[def.Key] as MyAnimationControllerDefinition;
                        if (originalAnimationController != null)
                        {
                            foreach (var sm in modifyingAnimationController.StateMachines)
                            {
                                bool found = false;
                                foreach (var smOrig in originalAnimationController.StateMachines)
                                {
                                    if (sm.Name == smOrig.Name)
                                    {
                                        smOrig.Nodes       = sm.Nodes;
                                        smOrig.Transitions = sm.Transitions;
                                        found = true;
                                        break;
                                    }
                                }

                                if (!found)
                                {
                                    originalAnimationController.StateMachines.Add(sm);
                                }
                            }

                            foreach (var layer in modifyingAnimationController.Layers)
                            {
                                bool found = false;
                                foreach (var layerOrig in originalAnimationController.Layers)
                                {
                                    if (layer.Name == layerOrig.Name)
                                    {
                                        layerOrig.Name          = layer.Name;
                                        layerOrig.BoneMask      = layer.BoneMask;
                                        layerOrig.InitialSMNode = layer.InitialSMNode;
                                        layerOrig.StateMachine  = layer.StateMachine;
                                        layerOrig.Mode          = layer.Mode;
                                        found = true;
                                    }
                                }

                                if (!found)
                                {
                                    originalAnimationController.Layers.Add(layer);
                                }
                            }

                            // TODO: IK?

                            justCopy = false;
                        }
                    }

                    if (justCopy)
                    {
                        currentDefinitions.Definitions[def.Key] = def.Value;
                    }
                }
            }
        }
        // receiving messages
        private void LiveDebugging_ReceivedMessageHandler(MyExternalDebugStructures.CommonMsgHeader messageHeader, IntPtr messageData)
        {
            MyExternalDebugStructures.ACReloadInGameMsg msgReload;
            if (MyExternalDebugStructures.ReadMessageFromPtr(ref messageHeader, messageData, out msgReload))
            {
                try
                {
                    string acContentPath = msgReload.ACContentAddress;
                    string acAddress = msgReload.ACAddress;
                    string acName = msgReload.ACName;

                    MyObjectBuilder_Definitions allDefinitions; // = null;
                    // load animation controller definition from SBC file
                    if (MyObjectBuilderSerializer.DeserializeXML(acAddress, out allDefinitions) &&
                        allDefinitions.Definitions != null &&
                        allDefinitions.Definitions.Length > 0)
                    {
                        var firstDef = allDefinitions.Definitions[0];
                        MyModContext context = new MyModContext();
                        context.Init("AnimationControllerDefinition", acAddress, acContentPath);
                        MyAnimationControllerDefinition animationControllerDefinition = new MyAnimationControllerDefinition();
                        animationControllerDefinition.Init(firstDef, context);
                        MyStringHash animSubtypeNameHash = MyStringHash.GetOrCompute(acName);

                        // post process and update in def. manager
                        MyAnimationControllerDefinition originalAnimationControllerDefinition =
                            MyDefinitionManagerBase.Static.GetDefinition<MyAnimationControllerDefinition>(
                                animSubtypeNameHash);

                        var postprocessor = MyDefinitionManagerBase.GetPostProcessor(typeof(MyObjectBuilder_AnimationControllerDefinition));
                        if (postprocessor != null)
                        {
                            MyDefinitionPostprocessor.Bundle originalBundle = new MyDefinitionPostprocessor.Bundle
                            {
                                Context = MyModContext.BaseGame,
                                Definitions = new Dictionary<MyStringHash, MyDefinitionBase>
                                {
                                    {animSubtypeNameHash, originalAnimationControllerDefinition}
                                },
                                Set = new MyDefinitionSet()
                            };
                            originalBundle.Set.AddDefinition(originalAnimationControllerDefinition);

                            MyDefinitionPostprocessor.Bundle overridingBundle = new MyDefinitionPostprocessor.Bundle
                            {
                                Context = context,
                                Definitions = new Dictionary<MyStringHash, MyDefinitionBase>
                                {
                                    {animSubtypeNameHash, animationControllerDefinition}
                                },
                                Set = new MyDefinitionSet()
                            };
                            overridingBundle.Set.AddDefinition(animationControllerDefinition);

                            // postprocess -> override existing definition in memory
                            postprocessor.AfterLoaded(ref overridingBundle);
                            postprocessor.OverrideBy(ref originalBundle, ref overridingBundle);
                        }

                        // swap animation controller for each entity
                        foreach (var component in m_skinnedEntityComponents)
                        {
                            if (component != null && component.SourceId.SubtypeName == acName)
                            {
                                component.Clear();
                                component.InitFromDefinition(originalAnimationControllerDefinition, forceReloadMwm: true); // reload from original def that was modified by postprocessor
                                if (component.ReloadBonesNeeded != null)
                                    component.ReloadBonesNeeded();
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    MyLog.Default.WriteLine(e);
                }
            }
        }
        // Initialize state machine of one layer.
        private static bool InitLayerNodes(VRage.Animations.MyAnimationStateMachine layer, string stateMachineName, MyAnimationControllerDefinition animControllerDefinition,
            VRage.Animations.MyAnimationController animationController, string currentNodeNamePrefix = "")
        {
            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 + "/"))
                        result = false;
                }
                else
                {
                    if (objBuilderNode.AnimationTree == null)
                    {
                        // no animation tree, just skip
                        continue;
                    }

                    var smNode = new VRage.Animations.MyAnimationStateMachineNode(absoluteNodeName);
                    layer.AddNode(smNode);

                    var smNodeAnimTree = InitNodeAnimationTree(objBuilderNode.AnimationTree.Child);
                    smNode.RootAnimationNode = smNodeAnimTree;
                }
            }

            // 2nd step: generate transitions
            if (objBuilderStateMachine.Transitions != null)
            foreach (var objBuilderTransition in objBuilderStateMachine.Transitions)
            {
                int conditionConjunctionIndex = 0;
                do
                {
                    // generate transition for each condition conjunction
                    var transition = layer.AddTransition(objBuilderTransition.From, objBuilderTransition.To,
                        new VRage.Animations.MyAnimationStateMachineTransition()) as
                        VRage.Animations.MyAnimationStateMachineTransition;
                    // if ok, fill in conditions
                    if (transition != null)
                    {
                        transition.Name = MyStringId.GetOrCompute(objBuilderTransition.Name);
                        transition.TransitionTimeInSec = objBuilderTransition.TimeInSec;
                        transition.Sync = objBuilderTransition.Sync;
                        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);
            }

            return result;
        }