Пример #1
0
        private List <Action <float> > LoadAnimations(Animation[] animations, List <byte[]> byteBuffers)
        {
            var animationController = new List <Action <float> >();

            if (animations is null)
            {
                return(animationController);
            }
            if (byteBuffers is null)
            {
                throw new ArgumentNullException(nameof(byteBuffers));
            }
            var accessorBuffers = new Dictionary <int, Array>();

            TYPE[] GetBuffer <TYPE>(int accessorId) where TYPE : struct
            {
                if (accessorBuffers.TryGetValue(accessorId, out var buf))
                {
                    return(buf as TYPE[]);
                }
                var accessor = gltf.Accessors[accessorId];
                var view     = gltf.BufferViews[accessor.BufferView.Value];
                var buffer   = FromByteArray <TYPE>(byteBuffers[view.Buffer],
                                                    view.ByteOffset + accessor.ByteOffset, accessor.Count);

                accessorBuffers.Add(accessorId, buffer);
                return(buffer);
            }

            foreach (var animation in animations)
            {
                void AddAnimationControllerTranslate(AnimationChannel channel)
                {
                    var sampler       = animation.Samplers[channel.Sampler];
                    var bufferTimes   = GetBuffer <float>(sampler.Input);
                    var bufferOutput  = GetBuffer <Vector3>(sampler.Output);
                    var controlPoints = new ControlPoints <Vector3>(bufferTimes, bufferOutput);
                    var node          = gltf.Nodes[channel.Target.Node.Value];

                    void Interpolator(float t)
                    {
                        var inter        = controlPoints.FindPair(t);
                        var interpolated = Vector3.Lerp(inter.Item1, inter.Item2, inter.Item3);

                        node.Translation = interpolated.ToArray();
                        localTransforms[channel.Target.Node.Value] = CreateLocalTransform(node);
                    }

                    animationController.Add(Interpolator);
                }

                void AddAnimationControllerRotation(AnimationChannel channel)
                {
                    var sampler       = animation.Samplers[channel.Sampler];
                    var bufferTimes   = GetBuffer <float>(sampler.Input);
                    var bufferOutput  = GetBuffer <Quaternion>(sampler.Output);
                    var controlPoints = new ControlPoints <Quaternion>(bufferTimes, bufferOutput);
                    var node          = gltf.Nodes[channel.Target.Node.Value];

                    void Interpolator(float t)
                    {
                        var inter        = controlPoints.FindPair(t);
                        var interpolated = Quaternion.Lerp(inter.Item1, inter.Item2, inter.Item3);

                        node.Rotation = interpolated.ToArray();
                        localTransforms[channel.Target.Node.Value] = CreateLocalTransform(node);
                    }

                    animationController.Add(Interpolator);
                }

                void AddAnimationControllerScale(AnimationChannel channel)
                {
                    var sampler       = animation.Samplers[channel.Sampler];
                    var bufferTimes   = GetBuffer <float>(sampler.Input);
                    var node          = gltf.Nodes[channel.Target.Node.Value];
                    var bufferOutput  = GetBuffer <Vector3>(sampler.Output);
                    var controlPoints = new ControlPoints <Vector3>(bufferTimes, bufferOutput);

                    void Interpolator(float t)
                    {
                        var inter        = controlPoints.FindPair(t);
                        var interpolated = Vector3.Lerp(inter.Item1, inter.Item2, inter.Item3);

                        node.Scale = interpolated.ToArray();
                        localTransforms[channel.Target.Node.Value] = CreateLocalTransform(node);
                    }

                    animationController.Add(Interpolator);
                }

                foreach (var channel in animation.Channels)
                {
                    if (!channel.Target.Node.HasValue)
                    {
                        continue;
                    }
                    switch (channel.Target.Path)
                    {
                    case AnimationChannelTarget.PathEnum.rotation:
                        AddAnimationControllerRotation(channel);
                        break;

                    case AnimationChannelTarget.PathEnum.translation:
                        AddAnimationControllerTranslate(channel);
                        break;

                    case AnimationChannelTarget.PathEnum.scale:
                        AddAnimationControllerScale(channel);
                        break;

                    default:
                        break;
                    }
                }
            }
            return(animationController);
        }