Ejemplo n.º 1
0
        public void StartAnimation(SpriteRenderer renderer, AnimTrack animTrack, bool loop, float speed = 7)
        {
            if (_activeAnimations.TryGetValue(renderer, out Animation animation))
            {
                animation.Speed  = speed;
                animation.Loop   = loop;
                animation.Sleeps = false;

                if (animation.AnimTrack != animTrack)
                {
                    animation.AnimTrack = animTrack;
                    animation.Sprites   = _config.Sequences.Find(sequence => sequence.Track == animTrack).Sprites;
                    animation.Counter   = 0;
                }
            }
            else
            {
                _activeAnimations.Add(renderer, new Animation
                {
                    AnimTrack = animTrack,
                    Sprites   = _config.Sequences.Find(sequence => sequence.Track == animTrack).Sprites,
                    Speed     = speed,
                    Loop      = loop
                });
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Reads the data out of the given track.
        /// </summary>
        /// <param name="track"></param>
        /// <returns></returns>
        public object[] ReadTrack(AnimTrack track)
        {
            //Console.WriteLine(Track.Name + " " + Track.Flags.ToString("X") + " " + Track.FrameCount + " " + Track.DataOffset.ToString("X"));
            List <object> output = new List <object>();

            using (SsbhParser parser = new SsbhParser(new MemoryStream(animFile.Buffer)))
            {
                parser.Seek(track.DataOffset);

                if (CheckFlag(track.Flags, 0xFF00, AnimTrackFlags.Constant))
                {
                    output.Add(ReadDirect(parser, track.Flags));
                }
                if (CheckFlag(track.Flags, 0xFF00, AnimTrackFlags.ConstTransform))
                {
                    // TODO: investigate more
                    output.Add(ReadDirect(parser, track.Flags));
                }
                if (CheckFlag(track.Flags, 0xFF00, AnimTrackFlags.Direct))
                {
                    for (int i = 0; i < track.FrameCount; i++)
                    {
                        output.Add(ReadDirect(parser, track.Flags));
                    }
                }
                if (CheckFlag(track.Flags, 0xFF00, AnimTrackFlags.Compressed))
                {
                    output.AddRange(ReadCompressed(parser, track.Flags));
                }
            }

            return(output.ToArray());
        }
Ejemplo n.º 3
0
 protected Spine.Animation GetCurrentAnim(AnimTrack track)
 {
     if (CurrectTrackEntry(track) == null)
     {
         return(null);
     }
     return(CurrectTrackEntry(track).Animation);
 }
Ejemplo n.º 4
0
 public ModelTimelineTrack(AnimTrack track)
 {
     keys       = new List <Sce.Atf.Controls.Timelines.IKey>();
     this.track = track;
     foreach (AnimKeyframe key in track.Keys)
     {
         keys.Add(new ModelTimelineKey(track, key));
     }
 }
Ejemplo n.º 5
0
            private static AnimTrack ParseTrack(FileReader reader, GameVersion version, long startPos, bool rotation = false)
            {
                long pos = reader.Position;

                uint Offset = reader.ReadUInt16();

                if (Offset == 0)
                {
                    return(new AnimTrack());
                }

                reader.SeekBegin(startPos + Offset);
                var track = new AnimTrack(reader, version, rotation);

                reader.SeekBegin(pos + sizeof(ushort)); //Seek back to next offset
                return(track);
            }
Ejemplo n.º 6
0
        /// <summary>
        /// Adds a track to be encoded
        /// </summary>
        /// <param name="NodeName">target material/texture/mesh name</param>
        /// <param name="TrackName">Usually "Transform" or "Visibility" matches <see cref="ANIM_TYPE"/></param>
        /// <param name="Type"><see cref="ANIM_TYPE"/></param>
        /// <param name="Values">Supported types AnimTrackTransform, AnimTrackTexture, AnimTrackCustomVector4, bool, float, int</param>
        public void AddTrack(string nodeName, string trackName, ANIM_TYPE type, IList <object> values)
        {
            AnimNode node = GetNode(type, nodeName);

            AnimTrack track = new AnimTrack
            {
                FrameCount = (uint)values.Count,
                Name       = trackName
            };

            var tracks = node.Tracks;

            Array.Resize(ref tracks, tracks.Length + 1);
            tracks[tracks.Length - 1] = track;
            node.Tracks = tracks;

            trackToValues.Add(track, values);
        }
Ejemplo n.º 7
0
            public void Read(FileReader reader, GameVersion version)
            {
                long pos = reader.Position;

                reader.ReadSignature(4, "anod");
                BoneIndex     = reader.ReadUInt16();
                RotationFlags = reader.ReadUInt16();
                TranslateX    = ParseTrack(reader, version, pos);
                TranslateY    = ParseTrack(reader, version, pos);
                TranslateZ    = ParseTrack(reader, version, pos);
                RotationX     = ParseTrack(reader, version, pos, RotationFlags == 1);
                RotationY     = ParseTrack(reader, version, pos, RotationFlags == 1);
                RotationZ     = ParseTrack(reader, version, pos, RotationFlags == 1);
                ScaleX        = ParseTrack(reader, version, pos);
                ScaleY        = ParseTrack(reader, version, pos);
                ScaleZ        = ParseTrack(reader, version, pos);
                reader.ReadUInt16();//0x00
            }
Ejemplo n.º 8
0
        private bool AnimationLock(AnimTrack track)
        {
            if (GetCurrentAnim(track) == null)
            {
                return(false);
            }
            switch (GetCurrentAnim(track).Name)
            {
            case Anim.TAKING_OFF:
            case Anim.ATTACK_STRONG_STATIC:
            case Anim.ATTACK_STRONG_MOVING:
            case Anim.MOVE_JUMPING:
            case Anim.INTERACT_LOOT:
                DebugUI.Flash_AnimBlock();
                return(true);

            default:
                return(false);
            }
        }
Ejemplo n.º 9
0
    //
    private void InitObjects()
    {
        m_EditableObjects = null;

        Object[] activeGOs = Selection.GetFiltered(typeof(Animation), SelectionMode.Editable | SelectionMode.TopLevel);

        if (activeGOs.Length > 0)
        {
            m_EditableObjects = new AnimTrack[activeGOs.Length];
            int index = 0;
            foreach (Object obj in activeGOs)
            {
                AnimTrack aTrack = new AnimTrack(((Animation)obj).gameObject);
                if (aTrack.m_Animation)
                {
                    m_MaxSliderTime = Mathf.Max(m_MaxSliderTime, aTrack.m_Animation.length);
                }
                m_EditableObjects[index++] = aTrack;
            }
        }
    }
Ejemplo n.º 10
0
 protected void ClearAnim(AnimTrack track)
 {
     AnimationState.ClearTrack((int)track);
 }
Ejemplo n.º 11
0
        public object[] ReadTrack(AnimTrack Track)
        {
            Console.WriteLine(Track.Name + " " + Track.Flags.ToString() + " " + Track.FrameCount + " " + Track.DataOffset.ToString("X"));
            List <object> output = new List <object>();

            using (SSBHParser parser = new SSBHParser(new MemoryStream(AnimFile.Buffer)))
            {
                parser.Seek(Track.DataOffset);

                if (CheckFlag(Track.Flags, 0x00FF, ANIM_TRACKFLAGS.Boolean))
                {
                    if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.Animated))
                    {
                        int Unk_4      = parser.ReadInt16();
                        int TrackFlag  = parser.ReadInt16();
                        int Unk1       = parser.ReadInt16();
                        int Unk2       = parser.ReadInt16();
                        int DataStart  = parser.ReadInt32();
                        int FrameCount = parser.ReadInt32();

                        parser.Seek((int)Track.DataOffset + DataStart);
                        for (int i = 0; i < FrameCount; i++)
                        {
                            output.Add(new AnimTrackBool(parser.ReadBits(1) == 1));
                        }
                    }
                    else
                    if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.Constant))
                    {
                        output.Add(new AnimTrackBool(parser.ReadBits(1) == 1));
                    }
                }
                if (CheckFlag(Track.Flags, 0x00FF, ANIM_TRACKFLAGS.Vector4))
                {
                    if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.Animated))
                    {
                        int Unk_4      = parser.ReadInt16();
                        int TrackFlag  = parser.ReadInt16();
                        int Unk1       = parser.ReadInt16();
                        int Unk2       = parser.ReadInt16();
                        int DataStart  = parser.ReadInt32();
                        int FrameCount = parser.ReadInt32();

                        int[]   ByteCounts = new int[9];
                        int[]   BitCounts  = new int[9];
                        float[] Start      = new float[9];
                        float[] End        = new float[9];
                        for (int i = 0; i < 4; i++)
                        {
                            Start[i] = parser.ReadSingle();
                            End[i]   = parser.ReadSingle();
                            long Count = parser.ReadInt64();
                            long bytes = (Count >> 3);
                            int  bits  = ((int)Count & 0x7);

                            if ((i >= 0 && i <= 0 && (TrackFlag & 0x3) == 0x3) || //isotrophic scale
                                (i >= 0 && i <= 2 && (TrackFlag & 0x3) == 0x1) || //normal scale
                                (i > 2 && i <= 5 && (TrackFlag & 0x4) > 0) ||
                                (i > 5 && i <= 8 && (TrackFlag & 0x8) > 0))
                            {
                                //reads
                                {
                                    BitCounts[i]  = bits;
                                    ByteCounts[i] = (int)bytes;
                                }
                            }
                        }

                        float X = parser.ReadSingle();
                        float Y = parser.ReadSingle();
                        float Z = parser.ReadSingle();
                        float W = parser.ReadSingle();

                        parser.Seek((int)Track.DataOffset + DataStart);
                        for (int i = 0; i < FrameCount; i++)
                        {
                            AnimTrackCustomVector4 Vector = new AnimTrackCustomVector4();
                            for (int j = 0; j < 4; j++)
                            {
                                int ValueBitCount = ByteCounts[j] * 8 + BitCounts[j];
                                int Value         = parser.ReadBits(ValueBitCount);
                                int scale         = 0;
                                for (int k = 0; k < ValueBitCount; k++)
                                {
                                    scale |= 0x1 << k;
                                }

                                float FrameValue = Lerp(Start[j], End[j], 0, 1, Value / (float)scale);
                                if (float.IsNaN(FrameValue))
                                {
                                    FrameValue = 0;
                                }

                                switch (j)
                                {
                                case 0: if (ValueBitCount > 0)
                                    {
                                        Vector.X = FrameValue;
                                    }
                                    else
                                    {
                                        Vector.X = X;
                                    } break;

                                case 1: if (ValueBitCount > 0)
                                    {
                                        Vector.Y = FrameValue;
                                    }
                                    else
                                    {
                                        Vector.Y = Y;
                                    } break;

                                case 2: if (ValueBitCount > 0)
                                    {
                                        Vector.Z = FrameValue;
                                    }
                                    else
                                    {
                                        Vector.Z = Z;
                                    } break;

                                case 3: if (ValueBitCount > 0)
                                    {
                                        Vector.W = FrameValue;
                                    }
                                    else
                                    {
                                        Vector.W = W;
                                    } break;
                                }
                            }

                            output.Add(Vector);
                        }
                    }
                    else
                    if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.Constant))
                    {
                        output.Add(new AnimTrackCustomVector4()
                        {
                            X = parser.ReadSingle(),
                            Y = parser.ReadSingle(),
                            Z = parser.ReadSingle(),
                            W = parser.ReadSingle()
                        });
                    }
                }
                if (CheckFlag(Track.Flags, 0x00FF, ANIM_TRACKFLAGS.Transform))
                {
                    if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.Animated))
                    {
                        int Unk_4      = parser.ReadInt16();
                        int TrackFlag  = parser.ReadInt16();
                        int Unk1       = parser.ReadInt16();
                        int Unk2       = parser.ReadInt16();
                        int DataStart  = parser.ReadInt32();
                        int FrameCount = parser.ReadInt32();

                        int[]   ByteCounts = new int[9];
                        int[]   BitCounts  = new int[9];
                        float[] Start      = new float[9];
                        float[] End        = new float[9];
                        for (int i = 0; i < 9; i++)
                        {
                            Start[i] = parser.ReadSingle();
                            End[i]   = parser.ReadSingle();
                            long Count = parser.ReadInt64();
                            long bytes = (Count >> 3);
                            int  bits  = ((int)Count & 0x7);

                            if ((i >= 0 && i <= 0 && (TrackFlag & 0x3) == 0x3) || //isotrophic scale
                                (i >= 0 && i <= 2 && (TrackFlag & 0x3) == 0x1) || //normal scale
                                (i > 2 && i <= 5 && (TrackFlag & 0x4) > 0) ||
                                (i > 5 && i <= 8 && (TrackFlag & 0x8) > 0))
                            {
                                //reads
                                {
                                    BitCounts[i]  = bits;
                                    ByteCounts[i] = (int)bytes;
                                }
                            }
                        }

                        float XSCA = parser.ReadSingle();
                        float YSCA = parser.ReadSingle();
                        float ZSCA = parser.ReadSingle();
                        float XROT = parser.ReadSingle();
                        float YROT = parser.ReadSingle();
                        float ZROT = parser.ReadSingle();
                        float WROT = parser.ReadSingle();
                        float XPOS = parser.ReadSingle();
                        float YPOS = parser.ReadSingle();
                        float ZPOS = parser.ReadSingle();

                        parser.ReadInt32(); // ????

                        parser.Seek((int)Track.DataOffset + DataStart);
                        for (int i = 0; i < FrameCount; i++)
                        {
                            AnimTrackTransform Transform = new AnimTrackTransform();
                            for (int j = 0; j < 9; j++)
                            {
                                int ValueBitCount = ByteCounts[j] * 8 + BitCounts[j];
                                int Value         = parser.ReadBits(ValueBitCount);
                                int scale         = 0;
                                for (int k = 0; k < ValueBitCount; k++)
                                {
                                    scale |= 0x1 << k;
                                }

                                float FrameValue = Lerp(Start[j], End[j], 0, 1, Value / (float)scale);
                                if (float.IsNaN(FrameValue))
                                {
                                    FrameValue = 0;
                                }

                                if ((TrackFlag & 0x3) == 0x3)
                                {
                                    //Scale Isotropic
                                    if (j == 0)
                                    {
                                        Transform.SX = FrameValue;
                                        Transform.SY = FrameValue;
                                        Transform.SZ = FrameValue;
                                    }
                                }
                                else if ((TrackFlag & 0x3) == 0x1)
                                {
                                    //Scale normal
                                    switch (j)
                                    {
                                    case 0:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.SX = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.SX = XSCA;
                                        }
                                        break;

                                    case 1:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.SY = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.SY = YSCA;
                                        }
                                        break;

                                    case 2:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.SZ = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.SZ = ZSCA;
                                        }
                                        break;
                                    }
                                }
                                else
                                {
                                    Transform.SX = XSCA;
                                    Transform.SY = YSCA;
                                    Transform.SZ = ZSCA;
                                }

                                //Rotation
                                if ((TrackFlag & 0x4) > 0)
                                {
                                    switch (j)
                                    {
                                    case 3:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.RX = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.RX = XROT;
                                        }
                                        break;

                                    case 4:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.RY = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.RY = YROT;
                                        }
                                        break;

                                    case 5:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.RZ = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.RZ = ZROT;
                                        }
                                        break;
                                    }
                                }
                                else
                                {
                                    Transform.RX = XROT;
                                    Transform.RY = YROT;
                                    Transform.RZ = ZROT;
                                    Transform.RW = WROT;
                                }

                                // Position
                                if ((TrackFlag & 0x8) > 0)
                                {
                                    switch (j)
                                    {
                                    case 6:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.X = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.X = XPOS;
                                        }
                                        break;

                                    case 7:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.Y = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.Y = YPOS;
                                        }
                                        break;

                                    case 8:
                                        if (ValueBitCount > 0)
                                        {
                                            Transform.Z = FrameValue;
                                        }
                                        else
                                        {
                                            Transform.Z = ZPOS;
                                        }
                                        break;
                                    }
                                }
                                else
                                {
                                    Transform.X = XPOS;
                                    Transform.Y = YPOS;
                                    Transform.Z = ZPOS;
                                }
                            }
                            if ((TrackFlag & 0x4) > 0)
                            {
                                // Rotation w
                                bool Wflip = parser.ReadBits(1) == 1;// (TrackFlag & 0x1) == 0 ? parser.ReadBits(1) == 1 : true;

                                Transform.RW = (float)Math.Sqrt(Math.Abs(1 - (Transform.RX * Transform.RX + Transform.RY * Transform.RY + Transform.RZ * Transform.RZ)));

                                if (Wflip)
                                {
                                    Transform.RW = -Transform.RW;
                                }
                            }

                            output.Add(Transform);
                        }
                    }
                    else if (CheckFlag(Track.Flags, 0xFF00, ANIM_TRACKFLAGS.ConstTransform))
                    {
                        output.Add(new AnimTrackTransform()
                        {
                            SX = parser.ReadSingle(),
                            SY = parser.ReadSingle(),
                            SZ = parser.ReadSingle(),
                            RX = parser.ReadSingle(),
                            RY = parser.ReadSingle(),
                            RZ = parser.ReadSingle(),
                            RW = parser.ReadSingle(),
                            X  = parser.ReadSingle(),
                            Y  = parser.ReadSingle(),
                            Z  = parser.ReadSingle(),
                        });

                        parser.ReadInt32(); // ????
                    }
                }
            }

            return(output.ToArray());
        }
Ejemplo n.º 12
0
 protected TrackEntry AddAnim(AnimTrack track, string name, bool loop, float delay = -1)
 {
     return(AnimationState.AddAnimation((int)track, name, loop, delay != -1 ? delay : (CurrectTrackEntry(track) != null ? CurrectTrackEntry(track).MixDuration : 0F)));
 }
Ejemplo n.º 13
0
 protected TrackEntry AddAnimEmpty(AnimTrack track, float mixDuration, float delay = -1)
 {
     return(AnimationState.AddEmptyAnimation((int)track, mixDuration, delay != -1 ? delay : (CurrectTrackEntry(track) != null ? CurrectTrackEntry(track).MixDuration : 0F)));
 }
Ejemplo n.º 14
0
 public ModelTimelineKey(AnimTrack track)
 {
     this.track = track;
 }
Ejemplo n.º 15
0
        private void ReadFrameData(DataReader d, int offset, int count, uint dataOffset, int boneCount, AnimTrack Track)
        {
            for (int i = offset; i < offset + count; i++)
            {
                d.Seek((uint)(dataOffset + 4 * 4 * i));
                var flagOffset     = d.ReadUInt32();
                var keyFrameOffset = d.ReadUInt32();
                var keyDataOffset  = d.ReadUInt32();

                d.Seek(flagOffset);
                var boneIndex     = d.ReadInt16();
                var keyFrameCount = d.ReadByte();
                var flag          = d.ReadByte();

                var node = anim.TransformNodes[boneIndex + (flag == 0 ? boneCount : 0)];

                d.Seek(keyDataOffset);
                for (int k = 0; k < keyFrameCount; k++)
                {
                    var temp = d.Position;
                    d.Seek((uint)(keyFrameOffset + k * 2));
                    var frame = d.ReadInt16();
                    d.Seek(temp);

                    float[] animdata = new float[Track.DataCount];
                    for (int j = 0; j < Track.DataCount; j++)
                    {
                        switch (Track.DataType)
                        {
                        case 1:
                            animdata[j] = d.ReadInt16() / (float)short.MaxValue;
                            break;

                        case 2:
                            animdata[j] = d.ReadSingle();
                            break;

                        case 4:
                            animdata[j] = d.ReadInt16();
                            break;

                        default:
                            throw new NotImplementedException("Data Type " + Track.DataType + " not implemented");
                        }
                    }

                    switch (Track.Type)
                    {
                    case 1:
                        node.AddKey(frame, animdata[0], AnimationTrackFormat.TranslateX);
                        node.AddKey(frame, animdata[1], AnimationTrackFormat.TranslateY);
                        node.AddKey(frame, animdata[2], AnimationTrackFormat.TranslateZ);
                        break;

                    case 2:
                        var e = GenericBone.ToEulerAngles(new OpenTK.Quaternion(animdata[0], animdata[1], animdata[2], animdata[3]).Inverted());
                        node.AddKey(frame, e.X, AnimationTrackFormat.RotateX);
                        node.AddKey(frame, e.Y, AnimationTrackFormat.RotateY);
                        node.AddKey(frame, e.Z, AnimationTrackFormat.RotateZ);
                        break;

                    case 3:
                        node.AddKey(frame, animdata[0], AnimationTrackFormat.ScaleX);
                        node.AddKey(frame, animdata[1], AnimationTrackFormat.ScaleY);
                        node.AddKey(frame, animdata[2], AnimationTrackFormat.ScaleZ);
                        break;
                    }
                }
            }
        }
Ejemplo n.º 16
0
 public AnimTrackData(AnimTrack track, SsbhAnimTrackDecoder decoder)
 {
     Name   = track.Name;
     Values = decoder.ReadTrack(track);
 }
Ejemplo n.º 17
0
 protected TrackEntry CurrectTrackEntry(AnimTrack track)
 {
     return(AnimationState.GetCurrent((int)track));
 }
Ejemplo n.º 18
0
        public List <AnimSequence> GetAnimSequences()
        {
            var animSeqs = new List <AnimSequence>();

            List <string> boneNames = Bones.Select(b => b.Name).ToList();

            int boneCount = boneNames.Count;

            foreach (var info in Infos)
            {
                var seq = new AnimSequence
                {
                    Bones            = boneNames,
                    Name             = info.Name,
                    NumFrames        = info.NumRawFrames,
                    SequenceLength   = info.TrackTime / info.AnimRate,
                    RateScale        = 1,
                    RawAnimationData = new List <AnimTrack>()
                };

                for (int boneIdx = 0; boneIdx < boneCount; boneIdx++)
                {
                    var track = new AnimTrack
                    {
                        Positions = new List <Vector3>(),
                        Rotations = new List <Quaternion>()
                    };

                    for (int frameIdx = 0; frameIdx < seq.NumFrames; frameIdx++)
                    {
                        int srcIdx  = ((info.FirstRawFrame + frameIdx) * boneCount) + boneIdx;
                        var posVec  = Keys[srcIdx].Position;
                        var rotQuat = Keys[srcIdx].Rotation;
                        track.Positions.Add(new Vector3(posVec.X, posVec.Y * -1, posVec.Z));
                        track.Rotations.Add(new Quaternion(rotQuat.X, rotQuat.Y * -1, rotQuat.Z, rotQuat.W * -1));
                    }

                    //if all keys are identical, replace with a single key
                    if (track.Positions.Count > 1)
                    {
                        var firstKey = track.Positions[0];
                        if (track.Positions.TrueForAll(key => key == firstKey))
                        {
                            track.Positions.Clear();
                            track.Positions.Add(firstKey);
                        }
                    }
                    if (track.Rotations.Count > 1)
                    {
                        var firstKey = track.Rotations[0];
                        if (track.Rotations.TrueForAll(key => key == firstKey))
                        {
                            track.Rotations.Clear();
                            track.Rotations.Add(firstKey);
                        }
                    }

                    seq.RawAnimationData.Add(track);
                }

                animSeqs.Add(seq);
            }


            return(animSeqs);
        }
Ejemplo n.º 19
0
        //All Animsequences MUST have the same BoneLists!
        public static PSA CreateFrom(List <AnimSequence> animSeqs)
        {
            if (animSeqs == null)
            {
                throw new ArgumentNullException(nameof(animSeqs));
            }

            if (animSeqs.Count == 0)
            {
                throw new ArgumentException("No AnimSequences!", nameof(animSeqs));
            }
            var psa = new PSA
            {
                Bones = new List <PSABone>(),
                Infos = new List <PSAAnimInfo>(),
                Keys  = new List <PSAAnimKeys>()
            };

            int numBones = animSeqs[0].Bones.Count;

            for (int i = 0; i < numBones; i++)
            {
                psa.Bones.Add(new PSABone
                {
                    Name        = animSeqs[0].Bones[i],
                    ParentIndex = i == 0 ? -1 : 0
                });
            }

            int frameCount = 0;

            foreach (AnimSequence animSeq in animSeqs)
            {
                int numFrames = animSeq.NumFrames;
                psa.Infos.Add(new PSAAnimInfo
                {
                    Name          = animSeq.Name.Instanced,
                    Group         = "None",
                    TotalBones    = numBones,
                    KeyQuotum     = numBones * numFrames,
                    TrackTime     = numFrames,
                    AnimRate      = animSeq.NumFrames / animSeq.SequenceLength * animSeq.RateScale,
                    FirstRawFrame = frameCount,
                    NumRawFrames  = numFrames
                });
                frameCount += numFrames;

                if (animSeq.RawAnimationData is null)
                {
                    animSeq.DecompressAnimationData();
                }

                for (int frameIdx = 0; frameIdx < numFrames; frameIdx++)
                {
                    for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                    {
                        AnimTrack  animTrack = animSeq.RawAnimationData[boneIdx];
                        Vector3    posVec    = animTrack.Positions.Count > frameIdx ? animTrack.Positions[frameIdx] : animTrack.Positions[animTrack.Positions.Count - 1];
                        Quaternion rotQuat   = animTrack.Rotations.Count > frameIdx ? animTrack.Rotations[frameIdx] : animTrack.Rotations[animTrack.Rotations.Count - 1];
                        rotQuat = new Quaternion(rotQuat.X, rotQuat.Y * -1, rotQuat.Z, rotQuat.W * -1);
                        posVec  = new Vector3(posVec.X, posVec.Y * -1, posVec.Z);
                        psa.Keys.Add(new PSAAnimKeys
                        {
                            Position = posVec,
                            Rotation = rotQuat,
                            Time     = 1
                        });
                    }
                }
            }

            return(psa);
        }
Ejemplo n.º 20
0
 public ModelTimelineKey(AnimTrack track, AnimKeyframe key)
 {
     this.key   = key;
     this.track = track;
 }
Ejemplo n.º 21
0
 protected TrackEntry SetAnim(AnimTrack track, string name, bool loop)
 {
     return(AnimationState.SetAnimation((int)track, name, loop));
 }
Ejemplo n.º 22
0
 protected TrackEntry SetAnimEmpty(AnimTrack track, float mixDuration)
 {
     return(AnimationState.SetEmptyAnimation((int)track, mixDuration));
 }
Ejemplo n.º 23
0
        public void DecompressAnimationData()
        {
            var ms = new MemoryStream(CompressedAnimationData);

            RawAnimationData = new List <AnimTrack>();

            for (int i = 0; i < Bones.Count; i++)
            {
                int posOff     = TrackOffsets[i * 4];
                int numPosKeys = TrackOffsets[i * 4 + 1];
                int rotOff     = TrackOffsets[i * 4 + 2];
                int numRotKeys = TrackOffsets[i * 4 + 3];

                var track = new AnimTrack
                {
                    Positions = new List <Vector3>(numPosKeys),
                    Rotations = new List <Quaternion>(numRotKeys)
                };

                if (numPosKeys > 0)
                {
                    ms.JumpTo(posOff);

                    AnimationCompressionFormat compressionFormat = posCompression;

                    if (numPosKeys == 1)
                    {
                        compressionFormat = AnimationCompressionFormat.ACF_None;
                    }

                    for (int j = 0; j < numPosKeys; j++)
                    {
                        switch (compressionFormat)
                        {
                        case AnimationCompressionFormat.ACF_None:
                        case AnimationCompressionFormat.ACF_Float96NoW:
                            track.Positions.Add(new Vector3(ms.ReadFloat(), ms.ReadFloat(), ms.ReadFloat()));
                            break;

                        case AnimationCompressionFormat.ACF_IntervalFixed32NoW:
                        case AnimationCompressionFormat.ACF_Fixed48NoW:
                        case AnimationCompressionFormat.ACF_Fixed32NoW:
                        case AnimationCompressionFormat.ACF_Float32NoW:
                        case AnimationCompressionFormat.ACF_BioFixed48:
                            throw new NotImplementedException($"Translation keys in format {compressionFormat} cannot be read yet!");
                        }
                    }

                    if (keyEncoding == AnimationKeyFormat.AKF_VariableKeyLerp && numPosKeys > 1)
                    {
                        ms.JumpTo(ms.Position.Align(4));

                        var keyTimes = new List <int>(numPosKeys);
                        for (int j = 0; j < numPosKeys; j++)
                        {
                            keyTimes.Add(NumFrames > 0xFF ? ms.ReadUInt16() : ms.ReadByte());
                        }
                        //RawAnimationData should have either 1 key, or the same number of keys as frames.
                        //Lerp any missing keys
                        List <Vector3> tempPositions = track.Positions;
                        track.Positions = new List <Vector3>(NumFrames)
                        {
                            tempPositions[0]
                        };
                        for (int frameIdx = 1, keyIdx = 1; frameIdx < NumFrames; keyIdx++, frameIdx++)
                        {
                            if (keyIdx >= keyTimes.Count)
                            {
                                track.Positions.Add(track.Positions[frameIdx - 1]);
                            }
                            else if (keyTimes[keyIdx] == frameIdx)
                            {
                                track.Positions.Add(tempPositions[keyIdx]);
                            }
                            else
                            {
                                int nextFrame = keyTimes[keyIdx];
                                int prevFrame = frameIdx - 1;
                                for (int j = frameIdx; j < nextFrame; j++)
                                {
                                    float amount = (float)(j - prevFrame) / (nextFrame - prevFrame);
                                    track.Positions.Add(Vector3.Lerp(track.Positions[prevFrame], tempPositions[keyIdx], amount));
                                }
                                track.Positions.Add(tempPositions[keyIdx]);
                                frameIdx = nextFrame;
                            }
                        }
                    }
                }

                if (numRotKeys > 0)
                {
                    ms.JumpTo(rotOff);

                    AnimationCompressionFormat compressionFormat = rotCompression;

                    if (numRotKeys == 1)
                    {
                        compressionFormat = AnimationCompressionFormat.ACF_Float96NoW;
                    }
                    else if (compressedDataSource != MEGame.UDK)
                    {
                        ms.Skip(12 * 2); //skip mins and ranges
                    }

                    for (int j = 0; j < numRotKeys; j++)
                    {
                        switch (compressionFormat)
                        {
                        case AnimationCompressionFormat.ACF_None:
                            track.Rotations.Add(new Quaternion(ms.ReadFloat(), ms.ReadFloat(), ms.ReadFloat(), ms.ReadFloat()));
                            break;

                        case AnimationCompressionFormat.ACF_Float96NoW:
                        {
                            float x = ms.ReadFloat();
                            float y = ms.ReadFloat();
                            float z = ms.ReadFloat();
                            track.Rotations.Add(new Quaternion(x, y, z, getW(x, y, z)));
                            break;
                        }

                        case AnimationCompressionFormat.ACF_BioFixed48:
                        {
                            const float shift         = 0.70710678118f;
                            const float scale         = 1.41421356237f;
                            const float precisionMult = 32767.0f;
                            ushort      a             = ms.ReadUInt16();
                            ushort      b             = ms.ReadUInt16();
                            ushort      c             = ms.ReadUInt16();
                            float       x             = (a & 0x7FFF) / precisionMult * scale - shift;
                            float       y             = (b & 0x7FFF) / precisionMult * scale - shift;
                            float       z             = (c & 0x7FFF) / precisionMult * scale - shift;
                            float       w             = getW(x, y, z);
                            int         wPos          = ((a >> 14) & 2) | ((b >> 15) & 1);
                            track.Rotations.Add(wPos switch
                                {
                                    0 => new Quaternion(w, x, y, z),
                                    1 => new Quaternion(x, w, y, z),
                                    2 => new Quaternion(x, y, w, z),
                                    _ => new Quaternion(x, y, z, w)
                                });

                            break;
                        }
Ejemplo n.º 24
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillRectangle(backBrush, e.ClipRectangle);

            var graphOffsetX = 50;
            var graphOffsetY = 12;
            var graphWidth   = panel1.Width - graphOffsetX;
            var graphHeight  = panel1.Height - graphOffsetY;

            float ampHi = float.MinValue;
            float ampLw = float.MaxValue;

            var keyCount = (float)KeyFrames.Count;

            var spaces = (int)(keyCount / (graphWidth / TextRenderer.MeasureText(keyCount.ToString(), numFont).Width));

            if (spaces < 1)
            {
                spaces = 1;
            }
            if (spaces % 5 != 0)
            {
                spaces += 5 - (spaces % 5);
            }

            AnimTrack a = new AnimTrack();

            a.Keys = GetFOBJKeys();

            for (int i = 0; i < KeyFrames.Count; i++)
            {
                var v = a.GetValue(i);

                ampHi = Math.Max(ampHi, v);
                ampLw = Math.Min(ampLw, v);
            }

            var dis = ampHi - ampLw;
            var off = dis * 0.15f;

            if (dis == 0)
            {
                return;
            }

            dis = (ampHi - ampLw) + off * 2;

            e.Graphics.DrawString(ampHi.ToString("0.0000"), numFont, numBrush, new PointF(0, (off / dis) * graphHeight - 4 + graphOffsetY));
            e.Graphics.DrawString(ampLw.ToString("0.0000"), numFont, numBrush, new PointF(0, ((dis - off) / dis) * graphHeight - 4 + graphOffsetY));

            e.Graphics.DrawLine(faintLinePen, new PointF(graphOffsetX, (off / dis) * graphHeight + graphOffsetY), new PointF(panel1.Width, (off / dis) * graphHeight + graphOffsetY));
            e.Graphics.DrawLine(faintLinePen, new PointF(graphOffsetX, ((dis - off) / dis) * graphHeight + graphOffsetY), new PointF(panel1.Width, ((dis - off) / dis) * graphHeight + graphOffsetY));


            for (int i = 1; i <= KeyFrames.Count; i++)
            {
                var x1 = graphOffsetX + (int)(((i - 1) / keyCount) * graphWidth);
                var h1 = (int)((a.GetValue(i - 1) + Math.Abs(ampLw) + off) / dis * graphHeight);
                var h2 = (int)((a.GetValue(i) + Math.Abs(ampLw) + off) / dis * graphHeight);

                if (i - 1 < KeyFrames.Count)
                {
                    if (KeyFrames[i - 1].InterpolationType == GXInterpolationType.HSD_A_OP_CON)
                    {
                        h2 = h1;
                    }
                }

                if (((i - 1) % spaces) == 0)
                {
                    e.Graphics.DrawLine(faintLinePen, new Point(x1, graphOffsetY), new Point(x1, panel1.Height));
                    e.Graphics.DrawString((i - 1).ToString(), numFont, numBrush, new PointF(x1 - 4, 0));
                }

                var px1 = graphOffsetX + (int)(((i - 1) / keyCount) * graphWidth);
                var px2 = graphOffsetX + (int)((i / keyCount) * graphWidth);
                var py1 = panel1.Height - h1;
                var py2 = panel1.Height - h2;

                e.Graphics.DrawLine(linePen,
                                    new Point(px1, py1),
                                    new Point(px2, py2));

                if (i - 1 < KeyFrames.Count)
                {
                    if (KeyFrames[i - 1].InterpolationType != GXInterpolationType.HSD_A_OP_NONE)
                    {
                        e.Graphics.FillRectangle(pointBrush, new RectangleF(px1 - 2, py1 - 2, 4, 4));
                    }
                }
            }
        }