/// <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) { Debug.Assert(stateMachine is MyAnimationStateMachine, "Animation machine nodes must be inside animation state machine."); MyAnimationStateMachine animStateMachine = stateMachine as MyAnimationStateMachine; if (m_rootAnimationNode != null) { m_rootAnimationNode.Update(ref animStateMachine.CurrentUpdateData); } }
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); }
/// <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(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); }
/// <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; }
// 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; }
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 VRage.Animations.MyAnimationStateMachineTransition()) as VRage.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); }