Ejemplo n.º 1
0
        public static Animation ConvertFromAssimpScene(Ai.Scene aiScene, Ai.Animation aiAnimation, AnimationConverterOptions options)
        {
            var animation = new Animation(options.Version);

            animation.Duration = ConvertTime(aiAnimation.DurationInTicks, aiAnimation.TicksPerSecond);

            foreach (var aiChannel in aiAnimation.NodeAnimationChannels)
            {
                if (AssimpConverterCommon.MeshAttachmentNameRegex.IsMatch(aiChannel.NodeName))
                {
                    continue;
                }

                var nodeName = AssimpConverterCommon.UnescapeName(aiChannel.NodeName);

                var controller = new AnimationController(options.Version)
                {
                    TargetKind = TargetKind.Node,
                    TargetName = nodeName,
                    TargetId   = GetTargetIdForNode(aiScene.RootNode, nodeName)
                };

                var track = new KeyframeTrack(options.Version);

                // NodePRS only for now
                track.KeyframeType = KeyframeType.NodePRS;

                // Fetch the unique key frame timings from all position, rotation and scale keys.
                var keyframeTimings = aiChannel.PositionKeys
                                      .Select(x => x.Time)
                                      .Concat(aiChannel.RotationKeys.Select(x => x.Time))
                                      .Concat(aiChannel.ScalingKeys.Select(x => x.Time))
                                      .Distinct()
                                      .OrderBy(x => x);

                // Convert the times to our scale and save them.
                track.KeyframeTimings = keyframeTimings
                                        .Select(x => ConvertTime(x, aiAnimation.TicksPerSecond))
                                        .ToList();

                // Decompose the local transform of the affected node so we can use them as the base values for our keyframes
                aiScene.RootNode.FindNode(nodeName).Transform
                .Decompose(out var nodeBaseScale, out var nodeBaseRotation, out var nodeBaseTranslation);

                // Keep track of the last position, rotation and scale used to ensure that interpolation works properly
                var lastPosition = nodeBaseTranslation;
                var lastRotation = nodeBaseRotation;
                var lastScale    = nodeBaseScale;

                foreach (var time in keyframeTimings)
                {
                    // Start building the keyframe
                    var keyframe = new KeyframePRS(track.KeyframeType)
                    {
                        Position = new Vector3(lastPosition.X, lastPosition.Y, lastPosition.Z),
                        Rotation = new Quaternion(lastRotation.X, lastRotation.Y, lastRotation.Z, lastRotation.W),
                        Scale    = new Vector3(lastScale.X, lastScale.Y, lastScale.Z)
                    };

                    // Fetch the Assimp keys for this time
                    var aiPositionKey = aiChannel.PositionKeys.SingleOrDefault(x => x.Time == time);
                    var aiRotationKey = aiChannel.RotationKeys.SingleOrDefault(x => x.Time == time);
                    var aiScaleKey    = aiChannel.ScalingKeys.SingleOrDefault(x => x.Time == time);

                    if (aiPositionKey != default(Ai.VectorKey))
                    {
                        keyframe.Position = new Vector3(aiPositionKey.Value.X, aiPositionKey.Value.Y, aiPositionKey.Value.Z);
                        lastPosition      = aiPositionKey.Value;
                    }

                    if (aiRotationKey != default(Ai.QuaternionKey))
                    {
                        keyframe.Rotation = new Quaternion(aiRotationKey.Value.X, aiRotationKey.Value.Y, aiRotationKey.Value.Z,
                                                           aiRotationKey.Value.W);
                        lastRotation = aiRotationKey.Value;
                    }

                    if (aiScaleKey != default(Ai.VectorKey))
                    {
                        keyframe.Scale = new Vector3(aiScaleKey.Value.X, aiScaleKey.Value.Y, aiScaleKey.Value.Z);
                        lastScale      = aiScaleKey.Value;
                    }

                    track.Keyframes.Add(keyframe);
                }

                controller.Tracks.Add(track);
                animation.Controllers.Add(controller);
            }

            return(animation);
        }
Ejemplo n.º 2
0
        public static Animation ConvertFromAssimpScene(string filePath, AnimationConverterOptions options)
        {
            var aiScene = AssimpSceneImporter.ImportFile(filePath);

            return(ConvertFromAssimpScene(aiScene, options));
        }
Ejemplo n.º 3
0
        public static Animation ConvertFromAssimpScene(Ai.Scene aiScene, AnimationConverterOptions options)
        {
            var aiAnimation = aiScene.Animations.FirstOrDefault();

            return(aiAnimation != null?ConvertFromAssimpScene(aiScene, aiAnimation, options) : null);
        }