예제 #1
0
        public AnimEvaluator(Assimp.Animation anim)
        {
            LastTime       = 0.0f;
            TicksPerSecond = anim.TicksPerSecond > 0.0f ? ( float )anim.TicksPerSecond : 920.0f;
            Duration       = ( float )anim.DurationInTicks;
            Name           = anim.Name;
            Channels       = new List <AnimChannel> ( );
            foreach (Assimp.NodeAnimationChannel channel in anim.NodeAnimationChannels)
            {
                AnimChannel nac = new AnimChannel();

                List <VectorKey> pk = new List <VectorKey> ( );
                List <QuatKey>   rk = new List <QuatKey> ( );
                List <VectorKey> sk = new List <VectorKey> ( );
                foreach (Assimp.VectorKey k in channel.PositionKeys)
                {
                    VectorKey npk = new VectorKey
                    {
                        Time  = k.Time,
                        Value = new OpenTK.Vector3(k.Value.X, k.Value.Y, k.Value.Z)
                    };

                    pk.Add(npk);
                }
                foreach (Assimp.QuaternionKey k in channel.RotationKeys)
                {
                    QuatKey nrk = new QuatKey
                    {
                        Time  = k.Time,
                        Value = new OpenTK.Quaternion(k.Value.X, k.Value.Y, k.Value.Z, k.Value.W)
                    };
                    rk.Add(nrk);
                }
                foreach (Assimp.VectorKey s in channel.ScalingKeys)
                {
                    VectorKey nsk = new VectorKey
                    {
                        Time  = s.Time,
                        Value = new OpenTK.Vector3(s.Value.X, s.Value.Y, s.Value.Z)
                    };
                    sk.Add(nsk);
                }
                nac.Name         = channel.NodeName;
                nac.PositionKeys = pk;
                nac.RotationKeys = rk;
                nac.ScalingKeys  = sk;
                Channels.Add(nac);
            }
            LastPositions        = Enumerable.Repeat(new MutableTuple <int, int, int> (0, 0, 0), anim.NodeAnimationChannelCount).ToList( );
            Transforms           = new List <List <OpenTK.Matrix4> > ( );
            PlayAnimationForward = true;
        }
예제 #2
0
        public void Evaluate(float dt, Dictionary <string, Bone> bones)
        {
            dt *= TicksPerSecond;
            float time = 0.0f;

            if (Duration > 0.0f)
            {
                time = dt % Duration;
            }
            for (int i = 0; i < Channels.Count; i++)
            {
                AnimChannel channel = Channels[i];
                if (!bones.ContainsKey(channel.Name))
                {
                    Console.WriteLine("Did not find the bone node " + channel.Name);
                    continue;
                }
                // interpolate position keyframes
                OpenTK.Vector3 pPosition = new OpenTK.Vector3( );
                if (channel.PositionKeys.Count > 0)
                {
                    int frame = (time >= LastTime) ? LastPositions[i].Item1 : 0;
                    while (frame < channel.PositionKeys.Count - 1)
                    {
                        if (time < channel.PositionKeys [frame + 1].Time)
                        {
                            break;
                        }
                        frame++;
                    }
                    if (frame >= channel.PositionKeys.Count)
                    {
                        frame = 0;
                    }

                    int nextFrame = (frame + 1) % channel.PositionKeys.Count;

                    VectorKey key      = channel.PositionKeys[frame];
                    VectorKey nextKey  = channel.PositionKeys[nextFrame];
                    double    diffTime = nextKey.Time - key.Time;
                    if (diffTime < 0.0)
                    {
                        diffTime += Duration;
                    }
                    if (diffTime > 0.0)
                    {
                        float factor = (float)((time - key.Time) / diffTime);
                        pPosition = key.Value + (nextKey.Value - key.Value) * factor;
                    }
                    else
                    {
                        pPosition = key.Value;
                    }
                    MutableTuple <int, int, int> tl = LastPositions [i];
                    tl.Item1 = frame;
                    LastPositions [i].Item1 = frame;
                }
                // interpolate rotation keyframes

                OpenTK.Quaternion pRot = new OpenTK.Quaternion(0, 0, 0, 1);
                if (channel.RotationKeys.Count > 0)
                {
                    int frame = (time >= LastTime) ? LastPositions[i].Item2 : 0;
                    while (frame < channel.RotationKeys.Count - 1)
                    {
                        if (time < channel.RotationKeys [frame + 1].Time)
                        {
                            break;
                        }
                        frame++;
                    }
                    if (frame >= channel.RotationKeys.Count)
                    {
                        frame = 0;
                    }
                    int nextFrame = (frame + 1) % channel.RotationKeys.Count;

                    QuatKey key     = channel.RotationKeys[frame];
                    QuatKey nextKey = channel.RotationKeys[nextFrame];
                    key.Value.Normalize( );
                    nextKey.Value.Normalize( );
                    double diffTime = nextKey.Time - key.Time;
                    if (diffTime < 0.0)
                    {
                        diffTime += Duration;
                    }
                    if (diffTime > 0)
                    {
                        float factor = (float)((time - key.Time) / diffTime);
                        pRot = OpenTK.Quaternion.Slerp(key.Value, nextKey.Value, factor);
                    }
                    else
                    {
                        pRot = key.Value;
                    }
                    LastPositions [i].Item1 = frame;
                }
                // interpolate scale keyframes
                OpenTK.Vector3 pscale = new OpenTK.Vector3(1);
                if (channel.ScalingKeys.Count > 0)
                {
                    int frame = (time >= LastTime) ? LastPositions[i].Item3 : 0;
                    while (frame < channel.ScalingKeys.Count - 1)
                    {
                        if (time < channel.ScalingKeys [frame + 1].Time)
                        {
                            break;
                        }
                        frame++;
                    }
                    if (frame >= channel.ScalingKeys.Count)
                    {
                        frame = 0;
                    }
                    LastPositions [i].Item3 = frame;
                }

                //OpenTK.Matrix4 mat = OpenTK.Matrix4.CreateFromQuaternion(pRot);

                // create the combined transformation matrix

                Assimp.Matrix4x4 mat = new Assimp.Matrix4x4(new Assimp.Quaternion(pRot.W, pRot.X, pRot.Y, pRot.Z).GetMatrix( ));

                mat.A1 *= pscale.X; mat.B1 *= pscale.X; mat.C1 *= pscale.X;
                mat.A2 *= pscale.Y; mat.B2 *= pscale.Y; mat.C2 *= pscale.Y;
                mat.A3 *= pscale.Z; mat.B3 *= pscale.Z; mat.C3 *= pscale.Z;
                mat.A4  = pPosition.X; mat.B4 = pPosition.Y; mat.C4 = pPosition.Z;

                // transpose to get DirectX style matrix
                //mat.Transpose();
                //mat.Inverse();

                bones [channel.Name].LocalTransform = ToTK(mat);
            }
            LastTime = time;
        }