internal SkinnedModelContent(ModelContent model, SkinnedModelBoneContentCollection skeleton,
     AnimationClipContentDictionary animationClips)
 {
     this.model = model;
     this.skeleton = skeleton;
     this.animationClips = animationClips;
 }
示例#2
0
 internal SkinnedModelContent(SkinnedModelMeshContentCollection meshes, SkinnedModelBoneContentCollection skeleton,
     AnimationClipContentDictionary animationClips)
 {
     this.meshes = meshes;
     this.skeleton = skeleton;
     this.animationClips = animationClips;
 }
        private bool ValidateAnimationChannel(
            KeyValuePair <string, AnimationChannel> animationChannelPair,
            AnimationContent parentAnimation, SkinnedModelBoneContentCollection boneCollection,
            ContentProcessorContext context)
        {
            // Check if this channel has any keyframe
            if (animationChannelPair.Value.Count == 0)
            {
                context.Logger.LogWarning(null, parentAnimation.Identity, String.Format(
                                              "Channel {0} in animation {1} does not contain any keyframe and will be skipped.",
                                              animationChannelPair.Key, parentAnimation.Name));

                return(false);
            }

            // Check if the animation channel exists in the skeleton
            bool boneFound = false;

            foreach (SkinnedModelBoneContent boneContent in boneCollection)
            {
                if (boneContent.Name.Equals(animationChannelPair.Key))
                {
                    boneFound = true;
                    break;
                }
            }

            if (!boneFound)
            {
                context.Logger.LogWarning(null, parentAnimation.Identity, String.Format(
                                              "Channel {0} in animation {1} affects a bone that does not exists in the " +
                                              "model's skeleton and will be skipped.", animationChannelPair.Key,
                                              parentAnimation.Name));

                return(false);
            }

            return(true);
        }
        public override SkinnedModelContent Process(NodeContent input, ContentProcessorContext context)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            BoneContent rootBone = MeshHelper.FindSkeleton(input);

            ValidateModel(input, rootBone, context);

            // Transform scene according to user defined rotation and scale
            TransformScene(input);

            // Processes model's meshes
            ProcessMeshes(input, context);

            // Processes model's skeleton
            SkinnedModelBoneContentCollection skinnedModelBoneCollection =
                ProcessBones(rootBone, context);

            // Processes model's animations
            AnimationClipContentDictionary animationClipDictionary =
                ProcessAnimations(input, rootBone.Animations, skinnedModelBoneCollection, context);

            OpaqueDataDictionary processorParameters = new OpaqueDataDictionary();

            processorParameters["DefaultEffect"] = MaterialProcessorDefaultEffect.SkinnedEffect;

            // Uses the default model processor
            ModelContent modelContent =
                context.Convert <NodeContent, ModelContent>(input, "ModelProcessor", processorParameters);

            // Return a new skinned model
            return(new SkinnedModelContent(modelContent, skinnedModelBoneCollection,
                                           animationClipDictionary));
        }
        private AnimationClipContentDictionary ProcessAnimations(NodeContent input,
                                                                 AnimationContentDictionary animationDictionary,
                                                                 SkinnedModelBoneContentCollection boneCollection,
                                                                 ContentProcessorContext context)
        {
            // Create a collection here (Does not need a dictionary here)
            Dictionary <string, AnimationClipContent> animationClipDictionary =
                new Dictionary <string, AnimationClipContent>();

            foreach (AnimationContent animation in animationDictionary.Values)
            {
                // Validate animation
                if (!ValidateAnimation(animation, context))
                {
                    continue;
                }

                Dictionary <string, AnimationChannelContent> animationChannelDictionary =
                    new Dictionary <string, AnimationChannelContent>();

                // Process each animation channel (One channel per bone)
                foreach (KeyValuePair <string, AnimationChannel> animationChannelPair in
                         animation.Channels)
                {
                    // Validate animation channel
                    if (!ValidateAnimationChannel(animationChannelPair, animation, boneCollection,
                                                  context))
                    {
                        continue;
                    }

                    List <AnimationKeyframeContent> keyframeList =
                        new List <AnimationKeyframeContent>(animationChannelPair.Value.Count);

                    // Process all the keyframes of that channel
                    foreach (AnimationKeyframe channelKeyframe in animationChannelPair.Value)
                    {
                        // Extract the keyframe pose from its transform matrix
                        Pose keyframePose;
                        channelKeyframe.Transform.Decompose(out keyframePose.Scale,
                                                            out keyframePose.Orientation, out keyframePose.Translation);

                        keyframeList.Add(
                            new AnimationKeyframeContent(channelKeyframe.Time, keyframePose));
                    }

                    // Sort the keyframes by time
                    keyframeList.Sort();

                    animationChannelDictionary.Add(animationChannelPair.Key,
                                                   new AnimationChannelContent(keyframeList));
                }

                AnimationClipContent animationClip = new AnimationClipContent(
                    animation.Name, new AnimationChannelContentDictionary(animationChannelDictionary),
                    animation.Duration);

                animationClipDictionary.Add(animation.Name, animationClip);
            }

            // Split animations
            if (!string.IsNullOrEmpty(splitAnimationFilename))
            {
                SplitAnimations(input, animationClipDictionary, context);
            }

            return(new AnimationClipContentDictionary(animationClipDictionary));
        }