示例#1
0
        /// <summary>
        ///     Model Matrix Data
        /// </summary>
        /// <param name="data"></param>
        /// <param name="ignoreVersion"></param>
        /// <param name="sectionHeader"></param>
        public G1MMatrix(Span <byte> data, bool ignoreVersion, ResourceSectionHeader sectionHeader)
        {
            if (sectionHeader.Magic != DataType.G1MM)
            {
                throw new InvalidOperationException("Not an G1MM stream");
            }

            Section = sectionHeader;
            if (!ignoreVersion && Section.Version.ToVersion() != SupportedVersion)
            {
                throw new NotSupportedException($"G1MM version {Section.Version.ToVersion()} is not supported!");
            }

            if (Section.Size == 0xC)
            {
                return;
            }

            var count = MemoryMarshal.Read <int>(data);

            if (count == 0)
            {
                return;
            }
            Matrices = MemoryMarshal.Cast <byte, Matrix4x4>(data.Slice(0x4)).ToArray();
        }
示例#2
0
 /// <summary>
 ///     Initialize with no data.
 /// </summary>
 public G1Model()
 {
     Section = new ResourceSectionHeader
     {
         Magic   = DataType.Model,
         Size    = -1,
         Version = SupportedVersion.ToVersionA()
     };
     SectionRoot = new PackedResource();
 }
示例#3
0
        /// <summary>
        ///     Extra data found in G1M models.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="ignoreVersion"></param>
        /// <param name="sectionHeader"></param>
        public G1Extra(Span <byte> data, bool ignoreVersion, ResourceSectionHeader sectionHeader)
        {
            if (sectionHeader.Magic != DataType.EXTR)
            {
                throw new InvalidOperationException("Not an EXTR stream");
            }

            Section = sectionHeader;
            if (!ignoreVersion && Section.Version.ToVersion() != SupportedVersion)
            {
                throw new NotSupportedException($"EXTR version {Section.Version.ToVersion()} is not supported!");
            }
        }
示例#4
0
        /// <summary>
        ///     Model Skeleton Data.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="ignoreVersion"></param>
        /// <param name="sectionHeader"></param>
        public G1MSkeleton(Span <byte> data, bool ignoreVersion, ResourceSectionHeader sectionHeader)
        {
            if (sectionHeader.Magic != DataType.G1MS)
            {
                throw new InvalidOperationException("Not an G1MS stream");
            }

            Section = sectionHeader;
            if (!ignoreVersion && Section.Version.ToVersion() != SupportedVersion)
            {
                throw new NotSupportedException($"G1MS version {Section.Version.ToVersion()} is not supported!");
            }

            Header      = MemoryMarshal.Read <ModelSkeletonHeader>(data);
            BoneIndices = MemoryMarshal.Cast <byte, short>(data.Slice(SizeHelper.SizeOf <ModelSkeletonHeader>(), Header.BoneTableCount)).ToArray();
            Bones       = MemoryMarshal.Cast <byte, ModelSkeletonBone>(data.Slice(Header.DataOffset - SizeHelper.SizeOf <ResourceSectionHeader>(), Header.BoneCount * SizeHelper.SizeOf <ModelSkeletonBone>())).ToArray();
        }
示例#5
0
        /// <summary>
        ///     Model Skeleton Data.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="ignoreVersion"></param>
        /// <param name="sectionHeader"></param>
        public G1MSkeleton(Span <byte> data, bool ignoreVersion, ResourceSectionHeader sectionHeader)
        {
            if (sectionHeader.Magic != DataType.G1MS)
            {
                throw new InvalidOperationException("Not an G1MS stream");
            }

            Section = sectionHeader;
            if (!ignoreVersion && Section.Version.ToVersion() != SupportedVersion)
            {
                throw new NotSupportedException($"G1MS version {Section.Version.ToVersion()} is not supported!");
            }

            Header      = MemoryMarshal.Read <ModelSkeletonHeader>(data);
            BoneIndices = MemoryMarshal.Cast <byte, short>(data.Slice(SizeHelper.SizeOf <ModelSkeletonHeader>(), Header.BoneTableCount)).ToArray();
            Bones       = MemoryMarshal.Cast <byte, ModelSkeletonBone>(data.Slice(Header.DataOffset - SizeHelper.SizeOf <ResourceSectionHeader>(), Header.BoneCount * SizeHelper.SizeOf <ModelSkeletonBone>())).ToArray();

            WorldBones = new ModelSkeletonBone[Bones.Length];
            for (var index = 0; index < Bones.Length; index++)
            {
                var bone = Bones[index];
                if (!bone.HasParent())
                {
                    WorldBones[index] = bone;
                    continue;
                }

                if (bone.Parent > index)
                {
                    throw new InvalidOperationException("Bone calculated before parent bone");
                }

                var parentBone = WorldBones[bone.Parent];
                WorldBones[index] = new ModelSkeletonBone
                {
                    Length   = bone.Length,
                    Parent   = bone.Parent,
                    Scale    = (parentBone.Scale.ToOpenTK() * bone.Scale.ToOpenTK()).ToDragon(),
                    Rotation = (parentBone.Rotation.ToOpenTK() * bone.Rotation.ToOpenTK()).ToDragon()
                };
                var local = parentBone.Rotation.ToOpenTK() * new Quaternion(bone.Position.ToOpenTK(), 0f) * new Quaternion(-parentBone.Rotation.X, -parentBone.Rotation.Y, -parentBone.Rotation.Z, parentBone.Rotation.W);
                WorldBones[index].Position = new Vector3(local.X + parentBone.Position.X, local.Y + parentBone.Position.Y, local.Z + parentBone.Position.Z);
            }
        }
示例#6
0
        private static void Main(string[] args)
        {
            Logger.PrintVersion("Nyotengu");
            var flags = CommandLineFlags.ParseFlags <KTIDFlags>(CommandLineFlags.PrintHelp, args);

            if (flags == null)
            {
                return;
            }

            var ndb = new NDB();

            if (!string.IsNullOrEmpty(flags.NDBPath) && File.Exists(flags.NDBPath))
            {
                ndb = new NDB(File.ReadAllBytes(flags.NDBPath));
            }

            var objdb    = new OBJDB(File.ReadAllBytes(flags.OBJDBPath));
            var filelist = Cethleann.ManagedFS.Nyotengu.LoadKTIDFileList(flags.FileList, flags.GameId);

            var textureSection = new ResourceSectionHeader
            {
                Magic   = DataType.TextureGroup,
                Version = 0x30303630
            };

            var textureHeader = new TextureGroupHeader
            {
                System = objdb.Header.System
            };

            foreach (var ktid in flags.Paths)
            {
                if (!File.Exists(ktid))
                {
                    continue;
                }
                var ktidgroup    = new KTIDTextureSet(File.ReadAllBytes(ktid));
                var ktidsystem   = ktidgroup.Textures.Select(x => objdb.Entries.TryGetValue(x, out var tuple) ? tuple : default).ToArray();
示例#7
0
        /// <summary>
        ///     Model Geometry
        /// </summary>
        /// <param name="data"></param>
        /// <param name="ignoreVersion"></param>
        /// <param name="sectionHeader"></param>
        public G1MGeometry(Span <byte> data, bool ignoreVersion, ResourceSectionHeader sectionHeader)
        {
            if (sectionHeader.Magic != DataType.G1MG)
            {
                throw new InvalidOperationException("Not an G1MG stream");
            }

            Section = sectionHeader;
            if (!ignoreVersion && Section.Version.ToVersion() != SupportedVersion)
            {
                throw new NotSupportedException($"G1MG version {Section.Version.ToVersion()} is not supported!");
            }

            Header = MemoryMarshal.Read <ModelGeometryHeader>(data);

            var offset = SizeHelper.SizeOf <ModelGeometryHeader>();

            while (offset < data.Length)
            {
                var subSectionHeader = MemoryMarshal.Read <ModelSection>(data.Slice(offset));
                var block            = data.Slice(offset + SizeHelper.SizeOf <ModelSection>(), subSectionHeader.Size - SizeHelper.SizeOf <ModelSection>());
                offset += subSectionHeader.Size;
                var section = subSectionHeader.Magic switch
                {
                    ModelGeometrySectionType.Socket => (IG1MGSection) new G1MGSocket(block, subSectionHeader),
                    ModelGeometrySectionType.Material => new G1MGMaterial(block, subSectionHeader),
                    ModelGeometrySectionType.ShaderParam => new G1MGShaderParam(block, subSectionHeader),
                    ModelGeometrySectionType.VertexBuffer => new G1MGVertexBuffer(block, subSectionHeader),
                    ModelGeometrySectionType.VertexAttribute => new G1MGVertexAttribute(block, subSectionHeader),
                    ModelGeometrySectionType.Bone => new G1MGBone(block, subSectionHeader),
                    ModelGeometrySectionType.IndexBuffer => new G1MGIndexBuffer(block, subSectionHeader),
                    ModelGeometrySectionType.SubMesh => new G1MGSubMesh(block, subSectionHeader),
                    ModelGeometrySectionType.Mesh => new G1MGMesh(block, subSectionHeader),
                    _ => throw new NotSupportedException($"Can't handle G1MG section {subSectionHeader.Magic:F}")
                };
                SubSections.Add(section);
            }
        }
        /// <summary>
        ///     Create a file with the given parameters
        /// </summary>
        /// <param name="header"></param>
        /// <param name="target"></param>
        /// <param name="version"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public Span <byte> WriteWithHeader <T>(T header, DataType target, int version) where T : struct
        {
            var length         = SizeHelper.SizeOf <T>() + Sections.Sum(x => x.Length) + SizeHelper.SizeOf <ResourceSectionHeader>();
            var buffer         = new Span <byte>(new byte[length]);
            var resourceHeader = new ResourceSectionHeader
            {
                Magic   = target,
                Size    = length,
                Version = version.ToVersionA()
            };

            MemoryMarshal.Write(buffer, ref resourceHeader);
            var pointer = SizeHelper.SizeOf <ResourceSectionHeader>();

            MemoryMarshal.Write(buffer.Slice(pointer), ref header);
            pointer += SizeHelper.SizeOf <T>();
            foreach (var stream in Sections)
            {
                stream.Span.CopyTo(buffer.Slice(pointer));
                pointer += stream.Length;
            }

            return(buffer);
        }
示例#9
0
 /// <summary>
 ///     Initialize with memory block
 /// </summary>
 /// <param name="dataBlock"></param>
 /// <param name="sectionHeader"></param>
 public G1MStub(Span <byte> dataBlock, ResourceSectionHeader sectionHeader)
 {
     Data    = new Memory <byte>(dataBlock.ToArray());
     Section = sectionHeader;
 }