/// <summary> /// Constructs a new animation player. /// </summary> public ClipPlayer(SkinningData skinningData) { if (skinningData == null) throw new ArgumentNullException("skinningData"); skinningDataValue = skinningData; boneTransforms = new Matrix[skinningData.BindPose.Count]; ActiveControlEvents = AnimationControlEvents.None; }
/// <summary> /// Constructs a new animation player. /// </summary> public ClipPlayer(SkinningData skinningData) { if (skinningData == null) { throw new ArgumentNullException("skinningData"); } skinningDataValue = skinningData; boneTransforms = new Matrix[skinningData.BindPose.Count]; ActiveControlEvents = AnimationControlEvents.None; }
public AnimationStateMachine(AnimationPackage package) { horizMovement = Vector2.Zero; mSkinningData = package.SkinningData; // Use the data in the AnimationPackage structure to create states to fill our list and build // a transition matrix. states = new Dictionary <string, AnimationState>(); foreach (AnimationStateDescription stateDesc in package.StateDescriptions) { AnimationState newState = new AnimationState(stateDesc, package); states.Add(newState.Name, newState); } transitions = new Dictionary <AnimationState, Dictionary <AnimationState, TransitionInfo> >(); foreach (KeyValuePair <string, AnimationState> currentStateKvp in states) { transitions.Add(currentStateKvp.Value, new Dictionary <AnimationState, TransitionInfo>()); foreach (KeyValuePair <string, AnimationState> nextStateKvp in states) { TransitionInfo bestFitTransition = null; foreach (TransitionInfo ti in package.Transitions) { // The items lower in the list are higher priority and will override previous matches. if (ti.IsMatch(currentStateKvp.Key, nextStateKvp.Key)) { bestFitTransition = ti; } } transitions[currentStateKvp.Value].Add(nextStateKvp.Value, bestFitTransition); } } CurrentState = states[package.InitialStateName]; desiredState = CurrentState; ActiveTransition = null; nextState = null; blendFromCancelledTransitionPose = false; ActiveControlEvents = AnimationControlEvents.None; }
public AnimationPackage( SkinningData skinningData, List<AnimationStateDescription> stateDescriptions, List<AnimationNodeDescription> nodeDescriptions, string initialStateName, List<TransitionInfo> transitions) { InitialStateName = initialStateName; SkinningData = skinningData; StateDescriptions = stateDescriptions; NodeDescriptions = new Dictionary<string, AnimationNodeDescription>(); foreach (AnimationNodeDescription and in nodeDescriptions) { NodeDescriptions.Add(and.Name, and); } Transitions = transitions; }
public AnimationPackage( SkinningData skinningData, List <AnimationStateDescription> stateDescriptions, List <AnimationNodeDescription> nodeDescriptions, string initialStateName, List <TransitionInfo> transitions) { InitialStateName = initialStateName; SkinningData = skinningData; StateDescriptions = stateDescriptions; NodeDescriptions = new Dictionary <string, AnimationNodeDescription>(); foreach (AnimationNodeDescription and in nodeDescriptions) { NodeDescriptions.Add(and.Name, and); } Transitions = transitions; }
public AnimationStateMachine(AnimationPackage package) { horizMovement = Vector2.Zero; mSkinningData = package.SkinningData; // Use the data in the AnimationPackage structure to create states to fill our list and build // a transition matrix. states = new Dictionary<string, AnimationState>(); foreach (AnimationStateDescription stateDesc in package.StateDescriptions) { AnimationState newState = new AnimationState(stateDesc, package); states.Add(newState.Name, newState); } transitions = new Dictionary<AnimationState, Dictionary<AnimationState, TransitionInfo>>(); foreach (KeyValuePair<string, AnimationState> currentStateKvp in states) { transitions.Add(currentStateKvp.Value, new Dictionary<AnimationState, TransitionInfo>()); foreach (KeyValuePair<string, AnimationState> nextStateKvp in states) { TransitionInfo bestFitTransition = null; foreach (TransitionInfo ti in package.Transitions) { // The items lower in the list are higher priority and will override previous matches. if (ti.IsMatch(currentStateKvp.Key, nextStateKvp.Key)) bestFitTransition = ti; } transitions[currentStateKvp.Value].Add(nextStateKvp.Value, bestFitTransition); } } CurrentState = states[package.InitialStateName]; desiredState = CurrentState; ActiveTransition = null; nextState = null; blendFromCancelledTransitionPose = false; ActiveControlEvents = AnimationControlEvents.None; }
/// <summary> /// Constructs a new animation player. /// </summary> public SkinClipPlayer(SkinningData skinningData) : base(skinningData) { worldTransforms = new Matrix[skinningData.BindPose.Count]; skinTransforms = new Matrix[skinningData.BindPose.Count]; }
/// <summary> /// The main Process method converts an intermediate format content pipeline /// NodeContent tree to a ModelContent object with embedded animation data. /// </summary> public override ModelContent Process(NodeContent input, ContentProcessorContext context) { ValidateMesh(input, context, null); // Find the skeleton. BoneContent skeleton = MeshHelper.FindSkeleton(input); if (skeleton == null) throw new InvalidContentException("Input skeleton not found."); // We don't want to have to worry about different parts of the model being // in different local coordinate systems, so let's just bake everything. FlattenTransforms(input, skeleton); // Read the bind pose and skeleton hierarchy data. IList<BoneContent> bones = MeshHelper.FlattenSkeleton(skeleton); // This value must match the constant of the same name in the Constants.fxh file. const int MAX_BONES = 72; if (bones.Count > MAX_BONES) { throw new InvalidContentException(string.Format( "Skeleton has {0} bones, but the maximum supported is {1}.", bones.Count, MAX_BONES)); } List<Matrix> bindPose = new List<Matrix>(); List<Matrix> inverseBindPose = new List<Matrix>(); List<int> skeletonHierarchy = new List<int>(); foreach (BoneContent bone in bones) { bindPose.Add(bone.Transform); inverseBindPose.Add(Matrix.Invert(bone.AbsoluteTransform)); skeletonHierarchy.Add(bones.IndexOf(bone.Parent as BoneContent)); } contentPath = Environment.CurrentDirectory; using (XmlReader reader = XmlReader.Create(MaterialDataFilePath)) { incomingMaterials = IntermediateSerializer.Deserialize<List<MaterialData>>(reader, null); } context.AddDependency(Path.Combine(Environment.CurrentDirectory, MaterialDataFilePath)); // Placeholder for when you could perform other ModelMeshPart/GeometryContent processing: //TraverseGeometryContents(input); AnimationPackageData incomingAnimation; using (XmlReader reader = XmlReader.Create(AnimationPackageDataFilePath)) { incomingAnimation = IntermediateSerializer.Deserialize<AnimationPackageData>(reader, null); } context.AddDependency(Path.Combine(Environment.CurrentDirectory, AnimationPackageDataFilePath)); // Convert animation data to our runtime format. Dictionary<string, Clip> animationClips; animationClips = ProcessAnimations(skeleton.Animations, bones, incomingAnimation.Clips); // Chain to the base ModelProcessor class so it can convert the model data. ModelContent model = base.Process(input, context); int modelMaxWeightsPerVert = 0; const string WEIGHTSPERVERT_PARAM_NAME = "gWeightsPerVert"; // Put the material's extra data into the ModelMeshPartContent's Tag property. // Also, note the largest value of "WeightsPerVert" used in any material. foreach (ModelMeshContent mmc in model.Meshes) { foreach (ModelMeshPartContent mmpc in mmc.MeshParts) { MaterialData mat = incomingMaterials.Single(m => m.Name == mmpc.Material.Name); MaterialInfo extraInfo = new MaterialInfo(); extraInfo.HandlingFlags = mat.HandlingFlags; extraInfo.RenderState = mat.RenderState; mmpc.Tag = extraInfo; EffectParam wpvEp = mat.EffectParams.Find(wpv => wpv.Name == WEIGHTSPERVERT_PARAM_NAME); if (wpvEp != null) { modelMaxWeightsPerVert = Math.Max(modelMaxWeightsPerVert, (int)(wpvEp.Value)); } } } // Store our custom animation data in the Tag property of the model. SkinningData skinningData = new SkinningData(animationClips, bindPose, inverseBindPose, skeletonHierarchy, modelMaxWeightsPerVert); model.Tag = new AnimationPackage( skinningData, incomingAnimation.AnimationStateDescriptions, incomingAnimation.AnimationNodeDescriptions, incomingAnimation.InitialStateName, incomingAnimation.Transitions); return model; }