Example #1
0
        static FQuat read_fixed32_quat(uint val, FVector min, FVector max)
        {
            var q = new FQuat
            {
                X = ((val >> 21) - 1023) / 1023f * max.X + min.X,
                Y = (((val & Y_MASK) >> 10) - 1023) / 1023f * max.Y + min.Y,
                Z = ((val & X_MASK) - 511) / 511f * max.Z + min.Z,
                W = 1
            };

            q.rebuild_w();
            return(q);
        }
Example #2
0
 internal FTransform(BinaryReader reader)
 {
     rotation    = new FQuat(reader);
     translation = new FVector(reader);
     scale_3d    = new FVector(reader);
 }
Example #3
0
        private FTrack[] read_tracks(MemoryStream stream)
        {
            if (key_encoding_format != 2)
            {
                throw new NotImplementedException("Can only parse PerTrackCompression");
            }
            using (stream)
                using (var reader = new BinaryReader(stream))
                {
                    var num_tracks = compressed_track_offsets.Length / 2;
                    var num_frames = compressed_num_frames;

                    FTrack[] ret = new FTrack[num_tracks];
                    for (int i = 0; i < ret.Length; i++)
                    {
                        FTrack track = new FTrack();

                        // translation
                        var offset = compressed_track_offsets[i * 2];
                        if (offset != -1)
                        {
                            var header = new FAnimKeyHeader(reader);
                            var min    = new FVector();
                            var max    = new FVector();

                            if (header.key_format == AnimationCompressionFormat.IntervalFixed32NoW)
                            {
                                if ((header.component_mask & 1) != 0)
                                {
                                    min.X = reader.ReadSingle();
                                    max.X = reader.ReadSingle();
                                }
                                if ((header.component_mask & 2) != 0)
                                {
                                    min.Y = reader.ReadSingle();
                                    max.Y = reader.ReadSingle();
                                }
                                if ((header.component_mask & 4) != 0)
                                {
                                    min.Z = reader.ReadSingle();
                                    max.Z = reader.ReadSingle();
                                }
                            }

                            track.translation = new FVector[header.num_keys];
                            for (int j = 0; j < track.translation.Length; j++)
                            {
                                switch (header.key_format)
                                {
                                case AnimationCompressionFormat.None:
                                case AnimationCompressionFormat.Float96NoW:
                                    var fvec = new FVector();
                                    if ((header.component_mask & 7) != 0)
                                    {
                                        if ((header.component_mask & 1) != 0)
                                        {
                                            fvec.X = reader.ReadSingle();
                                        }
                                        if ((header.component_mask & 2) != 0)
                                        {
                                            fvec.Y = reader.ReadSingle();
                                        }
                                        if ((header.component_mask & 4) != 0)
                                        {
                                            fvec.Z = reader.ReadSingle();
                                        }
                                    }
                                    else
                                    {
                                        fvec = new FVector(reader);
                                    }
                                    track.translation[j] = fvec;
                                    break;

                                case AnimationCompressionFormat.Fixed48NoW:
                                    fvec = new FVector();
                                    if ((header.component_mask & 1) != 0)
                                    {
                                        fvec.X = read_fixed48(reader.ReadUInt16());
                                    }
                                    if ((header.component_mask & 2) != 0)
                                    {
                                        fvec.Y = read_fixed48(reader.ReadUInt16());
                                    }
                                    if ((header.component_mask & 4) != 0)
                                    {
                                        fvec.Z = read_fixed48(reader.ReadUInt16());
                                    }
                                    track.translation[j] = fvec;
                                    break;

                                case AnimationCompressionFormat.IntervalFixed32NoW:
                                    track.translation[j] = read_fixed32_vec(reader.ReadUInt32(), min, max);
                                    break;
                                }
                            }
                            if (header.has_time_tracks)
                            {
                                track.translation_times = read_times(reader, header.num_keys, (uint)num_frames);
                            }
                            align_reader(reader);
                        }

                        // rotation
                        offset = compressed_track_offsets[(i * 2) + 1];
                        if (offset != -1)
                        {
                            var header = new FAnimKeyHeader(reader);
                            var min    = new FVector();
                            var max    = new FVector();

                            if (header.key_format == AnimationCompressionFormat.IntervalFixed32NoW)
                            {
                                if ((header.component_mask & 1) != 0)
                                {
                                    min.X = reader.ReadSingle();
                                    max.X = reader.ReadSingle();
                                }
                                if ((header.component_mask & 2) != 0)
                                {
                                    min.Y = reader.ReadSingle();
                                    max.Y = reader.ReadSingle();
                                }
                                if ((header.component_mask & 4) != 0)
                                {
                                    min.Z = reader.ReadSingle();
                                    max.Z = reader.ReadSingle();
                                }
                            }

                            track.rotation = new FQuat[header.num_keys];
                            for (int j = 0; j < track.rotation.Length; j++)
                            {
                                switch (header.key_format)
                                {
                                case AnimationCompressionFormat.None:
                                case AnimationCompressionFormat.Float96NoW:
                                    var fvec = new FVector();
                                    if ((header.component_mask & 7) != 0)
                                    {
                                        if ((header.component_mask & 1) != 0)
                                        {
                                            fvec.X = reader.ReadSingle();
                                        }
                                        if ((header.component_mask & 2) != 0)
                                        {
                                            fvec.Y = reader.ReadSingle();
                                        }
                                        if ((header.component_mask & 4) != 0)
                                        {
                                            fvec.Z = reader.ReadSingle();
                                        }
                                    }
                                    else
                                    {
                                        fvec = new FVector(reader);
                                    }
                                    var fquat = new FQuat()
                                    {
                                        X = fvec.X,
                                        Y = fvec.Y,
                                        Z = fvec.Z
                                    };
                                    fquat.rebuild_w();
                                    track.rotation[j] = fquat;
                                    break;

                                case AnimationCompressionFormat.Fixed48NoW:
                                    fquat = new FQuat();
                                    if ((header.component_mask & 1) != 0)
                                    {
                                        fquat.X = read_fixed48_q(reader.ReadUInt16());
                                    }
                                    if ((header.component_mask & 2) != 0)
                                    {
                                        fquat.Y = read_fixed48_q(reader.ReadUInt16());
                                    }
                                    if ((header.component_mask & 4) != 0)
                                    {
                                        fquat.Z = read_fixed48_q(reader.ReadUInt16());
                                    }
                                    fquat.rebuild_w();
                                    track.rotation[j] = fquat;
                                    break;

                                case AnimationCompressionFormat.IntervalFixed32NoW:
                                    track.rotation[j] = read_fixed32_quat(reader.ReadUInt32(), min, max);
                                    break;
                                }
                            }
                            if (header.has_time_tracks)
                            {
                                track.rotation_times = read_times(reader, header.num_keys, (uint)num_frames);
                            }
                            align_reader(reader);
                        }

                        // scale
                        offset = compressed_scale_offsets.offset_data[i * compressed_scale_offsets.strip_size];
                        if (offset != -1)
                        {
                            var header = new FAnimKeyHeader(reader);
                            var min    = new FVector();
                            var max    = new FVector();

                            if (header.key_format == AnimationCompressionFormat.IntervalFixed32NoW)
                            {
                                if ((header.component_mask & 1) != 0)
                                {
                                    min.X = reader.ReadSingle();
                                    max.X = reader.ReadSingle();
                                }
                                if ((header.component_mask & 2) != 0)
                                {
                                    min.Y = reader.ReadSingle();
                                    max.Y = reader.ReadSingle();
                                }
                                if ((header.component_mask & 4) != 0)
                                {
                                    min.Z = reader.ReadSingle();
                                    max.Z = reader.ReadSingle();
                                }
                            }

                            track.scale = new FVector[header.num_keys];
                            for (int j = 0; j < track.scale.Length; j++)
                            {
                                switch (header.key_format)
                                {
                                case AnimationCompressionFormat.None:
                                case AnimationCompressionFormat.Float96NoW:
                                    var fvec = new FVector();
                                    if ((header.component_mask & 7) != 0)
                                    {
                                        if ((header.component_mask & 1) != 0)
                                        {
                                            fvec.X = reader.ReadSingle();
                                        }
                                        if ((header.component_mask & 2) != 0)
                                        {
                                            fvec.Y = reader.ReadSingle();
                                        }
                                        if ((header.component_mask & 4) != 0)
                                        {
                                            fvec.Z = reader.ReadSingle();
                                        }
                                    }
                                    else
                                    {
                                        fvec = new FVector(reader);
                                    }
                                    track.scale[j] = fvec;
                                    break;

                                case AnimationCompressionFormat.Fixed48NoW:
                                    fvec = new FVector();
                                    if ((header.component_mask & 1) != 0)
                                    {
                                        fvec.X = read_fixed48(reader.ReadUInt16());
                                    }
                                    if ((header.component_mask & 2) != 0)
                                    {
                                        fvec.Y = read_fixed48(reader.ReadUInt16());
                                    }
                                    if ((header.component_mask & 4) != 0)
                                    {
                                        fvec.Z = read_fixed48(reader.ReadUInt16());
                                    }
                                    track.scale[j] = fvec;
                                    break;

                                case AnimationCompressionFormat.IntervalFixed32NoW:
                                    track.scale[j] = read_fixed32_vec(reader.ReadUInt32(), min, max);
                                    break;
                                }
                            }
                            if (header.has_time_tracks)
                            {
                                track.scale_times = read_times(reader, header.num_keys, (uint)num_frames);
                            }
                            align_reader(reader);
                        }

                        ret[i] = track;
                    }

                    if (reader.BaseStream.Position != stream.Length)
                    {
                        throw new FileLoadException($"Could not read tracks correctly, {reader.BaseStream.Position - stream.Length} bytes remaining");
                    }
                    return(ret);
                }
        }