Esempio n. 1
0
        public override void Load(ExtendedBinaryReader reader, bool keepOpen = false)
        {
            // Height of the character in pixels
            CharacterHeight = reader.ReadInt32();
            // The amount of characters defined
            int characterCount = reader.ReadInt32();

            // Unknown
            WidthScale  = reader.ReadSingle();
            HeightScale = reader.ReadSingle();

            for (int i = 0; i < characterCount; ++i)
            {
                var fontEntry = new FontEntry
                {
                    Character = ReadReversedUTF8Char(reader),   // The read UTF8 character
                    XScale    = reader.ReadSingle(),            // X position on the texture (Multiply by the textures width to get pixels)
                    YScale    = reader.ReadSingle(),            // Y position on the texture (Multiply by the textures height to get pixels)
                };
                if (!MonospaceOnly)
                {
                    fontEntry.Kerning = reader.ReadInt32();     // -X offset for positioning when rendering
                    fontEntry.Width   = reader.ReadInt32();     // The width of the character in pixels
                }
                else
                {
                    fontEntry.Width = CharacterHeight; // Force square character
                }

                Characters.Add(fontEntry);
            }
        }
        private static IDictionary <int, SizeF[]> ReadBoxSizes(string path)
        {
            var result = new Dictionary <int, SizeF[]>();
            var file   = System.IO.Path.Combine(path, "resources_00001.-13");

            using (var fs = new FileStream(file, FileMode.Open))
                using (var input = new ExtendedBinaryReader(fs))
                {
                    input.BaseStream.Seek(0x150, SeekOrigin.Begin);

                    var heightCount = input.ReadInt32();
                    for (var i = 0; i < heightCount; i++)
                    {
                        var nameLength = input.ReadInt32();
                        var name       = input.ReadString();
                        var msgEnum    = input.ReadInt32();
                        var langCount  = input.ReadInt32();

                        var sizes = new SizeF[langCount];
                        for (var j = 0; j < langCount; j++)
                        {
                            var sz = new SizeF(input.ReadSingle(), input.ReadSingle());
                            sizes[j] = sz;
                        }

                        result.Add(msgEnum, sizes);
                    }
                }

            return(result);
        }
Esempio n. 3
0
        public override void Read(ExtendedBinaryReader reader, Action <Vector2> synchronizationCallback)
        {
            float x = reader.ReadSingle();
            float y = reader.ReadSingle();

            synchronizationCallback(new Vector2(x, y));
        }
Esempio n. 4
0
        public override void Deserialize(ExtendedBinaryReader reader, Action <Vector2> valueFixup)
        {
            float x = reader.ReadSingle();
            float y = reader.ReadSingle();

            valueFixup(new Vector2(x, y));
        }
Esempio n. 5
0
 public void Load(ExtendedBinaryReader reader)
 {
     SourceX = reader.ReadSingle();
     SourceY = reader.ReadSingle();
     DestinX = reader.ReadSingle();
     DestinY = reader.ReadSingle();
     reader.JumpAhead(0x30); // Unknown
 }
Esempio n. 6
0
        private static object ReadValueType(Type valueType, ExtendedBinaryReader br, bool noAlign = false)
        {
            if (!noAlign)
            {
                br.AlignStream();
            }

            if (valueType == typeof(string))
            {
                return(br.ReadAlignedString());
            }
            else if (valueType == typeof(Int32))
            {
                return(br.ReadInt32());
            }
            else if (valueType == typeof(UInt32))
            {
                return(br.ReadUInt32());
            }
            else if (valueType == typeof(Int64))
            {
                return(br.ReadInt64());
            }
            else if (valueType == typeof(UInt64))
            {
                return(br.ReadUInt64());
            }
            else if (valueType == typeof(Int16))
            {
                return(br.ReadInt16());
            }
            else if (valueType == typeof(UInt16))
            {
                return(br.ReadUInt16());
            }
            else if (valueType == typeof(Byte))
            {
                return(br.ReadByte());
            }
            else if (valueType == typeof(SByte))
            {
                return(br.ReadSByte());
            }
            else if (valueType == typeof(Boolean))
            {
                return(br.ReadBoolean());
            }
            else if (valueType == typeof(Double))
            {
                return(br.ReadDouble());
            }
            else if (valueType == typeof(Single))
            {
                return(br.ReadSingle());
            }
            else
            {
                throw new ArgumentException($"{valueType} is not a value type");
            }
        }
Esempio n. 7
0
        public static void LoadLight(string filePath)
        {
            using (var fileStream = File.OpenRead(filePath))
            {
                var reader = new ExtendedBinaryReader(fileStream, true);

                uint fileSize            = reader.ReadUInt32();
                uint rootNodeType        = reader.ReadUInt32();
                uint finalTableOffset    = reader.ReadUInt32();
                uint rootNodeOffset      = reader.ReadUInt32();
                uint finalTableOffsetAbs = reader.ReadUInt32();
                uint padding             = reader.ReadUInt32();
                lightType = (LightType)reader.ReadUInt32();
                float XPos   = reader.ReadSingle();
                float YPos   = reader.ReadSingle();
                float ZPos   = reader.ReadSingle();
                float ColorR = reader.ReadSingle();
                float ColorG = reader.ReadSingle();
                float ColorB = reader.ReadSingle();

                // Generate XML
                var rootElement = new XElement("SonicLightXml");
                rootElement.Add(new XElement("LightType", lightType));

                var lightPosition = new XElement("Position");
                lightPosition.Add(new XElement("X", XPos));
                lightPosition.Add(new XElement("Y", YPos));
                lightPosition.Add(new XElement("Z", ZPos));
                rootElement.Add(lightPosition);

                var lightColor = new XElement("Color");
                lightColor.Add(new XElement("R", ColorR));
                lightColor.Add(new XElement("G", ColorG));
                lightColor.Add(new XElement("B", ColorB));
                rootElement.Add(lightColor);

                // Omni-Specific Values
                if (lightType == LightType.Omni)
                {
                    uint  Unknown1       = reader.ReadUInt32();
                    uint  Unknown2       = reader.ReadUInt32();
                    uint  Unknown3       = reader.ReadUInt32();
                    float OmniInnerRange = reader.ReadSingle();
                    float OmniOuterRange = reader.ReadSingle();

                    var OmniLightRange = new XElement("OmniLightRange");
                    OmniLightRange.Add(new XElement("OmniLightInnerRange", OmniInnerRange));
                    OmniLightRange.Add(new XElement("OmniLightOuterRange", OmniOuterRange));
                    rootElement.Add(OmniLightRange);
                }

                // Save the Generated XML File
                var xml = new XDocument(rootElement);
                xml.Save($"{filePath}.xml");
            }
        }
Esempio n. 8
0
        private void Load_Xex(string filename)
        {
            Xex_Name = Path.GetFileName(filename);
            Xex_File = File.ReadAllBytes(filename);
            RenderingRes_X_TextBox.Enabled = true;
            RenderingRes_Y_TextBox.Enabled = true;
            GammaColor_R_TextBox.Enabled   = true;
            GammaColor_G_TextBox.Enabled   = true;
            GammaColor_B_TextBox.Enabled   = true;

            SaveXex.Enabled = true;
            RestoreOriginalResBtn.Enabled     = true;
            RestoreOriginalGammaBtn.Enabled   = true;
            DisableGammaCorrectionBtn.Enabled = true;

            using (MemoryStream file = new MemoryStream(Xex_File))
                using (ExtendedBinaryReader read = new ExtendedBinaryReader(file, true))
                {
                    // Get Rendering Res -- In Order Of Xex File
                    file.Seek(0xBA5026, SeekOrigin.Begin);
                    RenderingRes_Y = read.ReadInt16();

                    file.Seek(0xBA502A, SeekOrigin.Begin);
                    RenderingRes_X = read.ReadInt16();

                    //Get Gamma Color -- In Order Of Xex File
                    file.Seek(0x1277450, SeekOrigin.Begin);
                    GammaColor_R = read.ReadSingle();

                    file.Seek(0x1277454, SeekOrigin.Begin);
                    GammaColor_G = read.ReadSingle();

                    file.Seek(0x1277458, SeekOrigin.Begin);
                    GammaColor_B = read.ReadSingle();
                }
            RenderingRes_X_TextBox.Text = RenderingRes_X.ToString();
            RenderingRes_Y_TextBox.Text = RenderingRes_Y.ToString();

            GammaColor_R_TextBox.Text = GammaColor_R.ToString();
            GammaColor_G_TextBox.Text = GammaColor_G.ToString();
            GammaColor_B_TextBox.Text = GammaColor_B.ToString();
        }
        protected virtual void LoadChanges(IList <Subtitle> subtitles)
        {
            if (HasChanges)
            {
                using (var fs = new FileStream(ChangesFile, FileMode.Open))
                    using (var input = new ExtendedBinaryReader(fs, System.Text.Encoding.Unicode))
                    {
                        var version = input.ReadInt32();

                        if (version != ChangesFileVersion)
                        {
                            //File.Delete(ChangesFile);
                            return;
                        }

                        var subtitleCount = input.ReadInt32();

                        for (var i = 0; i < subtitleCount; i++)
                        {
                            var offset = input.ReadInt64();
                            var text   = input.ReadString();
                            var width  = input.ReadSingle();
                            var height = input.ReadSingle();

                            var subtitle = subtitles.FirstOrDefault(x => x.Offset == offset);
                            if (subtitle != null)
                            {
                                subtitle.PropertyChanged -= SubtitlePropertyChanged;
                                subtitle.Translation      = text;
                                subtitle.Width            = width;
                                subtitle.Height           = height;
                                subtitle.Loaded           = subtitle.Translation;
                                subtitle.LoadedWidth      = subtitle.Width;
                                subtitle.LoadedHeight     = subtitle.Height;
                                subtitle.PropertyChanged += SubtitlePropertyChanged;
                            }
                        }
                    }
            }
        }
Esempio n. 10
0
        private void LoadFontTableChanges(CharacterInfo[] data)
        {
            if (HasChanges)
            {
                using (var fs = new FileStream(ChangesFile, FileMode.Open))
                    using (var input = new ExtendedBinaryReader(fs, Encoding.Unicode))
                    {
                        var version = input.ReadInt32();

                        if (version != ChangesFileVersion)
                        {
                            //System.IO.File.Delete(ChangesFile);
                            return;
                        }

                        for (var i = 0; i < 256; i++)
                        {
                            data[i][0] = input.ReadSingle();
                            data[i][1] = input.ReadSingle();
                            data[i][2] = input.ReadSingle();
                            data[i][3] = input.ReadSingle();
                            data[i][4] = input.ReadSingle();
                            data[i][5] = input.ReadSingle();
                        }
                    }
            }
        }
Esempio n. 11
0
            public void Load(ExtendedBinaryReader reader)
            {
                LayerName = reader.ReadSignature(0x20);
                uint unknown20 = reader.ReadUInt32();

                TextureID = reader.ReadInt32();
                uint Offset    = reader.ReadUInt32();
                uint unknown2C = reader.ReadUInt32();

                //
                uint oldpos = (uint)reader.GetPosition();

                reader.JumpTo(Offset);

                reader.JumpAhead(0x164);
                LayerOffX = reader.ReadSingle();
                LayerOffY = reader.ReadSingle();
                reader.JumpAhead(4);
                LayerWidth  = reader.ReadSingle();
                LayerHeight = reader.ReadSingle();

                reader.JumpAhead(0x88); // Unknown

                /*
                 * Top Left
                 * Top Right
                 * Bottom Left
                 * Bottom Right
                 */

                for (int i = 0; i < 4; ++i)
                {
                    Verts.Add(new MAVert(reader));
                }

                reader.JumpTo(oldpos);

                reader.JumpAhead(0x84); // Unknown
            }
Esempio n. 12
0
        public void LoadLight(string filePath)
        {
            using (var fileStream = File.OpenRead(filePath))
            {
                var   reader              = new ExtendedBinaryReader(fileStream, true);
                uint  fileSize            = reader.ReadUInt32();
                uint  rootNodeType        = reader.ReadUInt32();
                uint  finalTableOffset    = reader.ReadUInt32();
                uint  rootNodeOffset      = reader.ReadUInt32();
                uint  finalTableOffsetAbs = reader.ReadUInt32();
                uint  padding             = reader.ReadUInt32();
                uint  value_LightType     = reader.ReadUInt32();
                float XPos   = reader.ReadSingle();
                float YPos   = reader.ReadSingle();
                float ZPos   = reader.ReadSingle();
                float ColorR = reader.ReadSingle();
                float ColorG = reader.ReadSingle();
                float ColorB = reader.ReadSingle();

                // Read Omni-Specific Values
                bool isOmniLight = (value_LightType == 1);
                if (isOmniLight)
                {
                    uint  Unknown1       = reader.ReadUInt32();
                    uint  Unknown2       = reader.ReadUInt32();
                    uint  Unknown3       = reader.ReadUInt32();
                    float OmniInnerRange = reader.ReadSingle();
                    float OmniOuterRange = reader.ReadSingle();

                    TextBoxOmniLightInnerRange.Text = OmniInnerRange.ToString();
                    TextBoxOmniLightOuterRange.Text = OmniOuterRange.ToString();
                }

                // Update UI Elements
                TextBoxPosX.Text   = XPos.ToString();
                TextBoxPosY.Text   = YPos.ToString();
                TextBoxPosZ.Text   = ZPos.ToString();
                TextBoxColorR.Text = ColorR.ToString();
                TextBoxColorG.Text = ColorG.ToString();
                TextBoxColorB.Text = ColorB.ToString();

                LightType.Text = string.Format("Light Type: {0}",
                                               (isOmniLight) ? "Omni" : "Directional");

                RefreshUI(true, isOmniLight);
            }
        }
        public static void LoadLight(string filePath)
        {
            using (var fileStream = File.OpenRead(filePath))
            {
                var   reader              = new ExtendedBinaryReader(fileStream, true);
                uint  fileSize            = reader.ReadUInt32();
                uint  rootNodeType        = reader.ReadUInt32();
                uint  finalTableOffset    = reader.ReadUInt32();
                uint  rootNodeOffset      = reader.ReadUInt32();
                uint  finalTableOffsetAbs = reader.ReadUInt32();
                uint  padding             = reader.ReadUInt32();
                uint  value_LightType     = reader.ReadUInt32();
                float XPos   = reader.ReadSingle();
                float YPos   = reader.ReadSingle();
                float ZPos   = reader.ReadSingle();
                float ColorR = reader.ReadSingle();
                float ColorG = reader.ReadSingle();
                float ColorB = reader.ReadSingle();

                // Print out Light information
                Console.WriteLine($"Light type: {value_LightType}");
                Console.WriteLine($"PosX: {XPos}");
                Console.WriteLine($"PosY: {YPos}");
                Console.WriteLine($"PosZ: {ZPos}");
                Console.WriteLine($"ColorR: {ColorR}");
                Console.WriteLine($"ColorG: {ColorG}");
                Console.WriteLine($"ColorB: {ColorB}");

                // Read Omni-Specific Values and print them, if present.
                bool isOmniLight = (value_LightType == 1);
                if (isOmniLight)
                {
                    uint  Unknown1       = reader.ReadUInt32();
                    uint  Unknown2       = reader.ReadUInt32();
                    uint  Unknown3       = reader.ReadUInt32();
                    float OmniInnerRange = reader.ReadSingle();
                    float OmniOuterRange = reader.ReadSingle();

                    Console.WriteLine($"OmniLightInnerRange: {OmniInnerRange}");
                    Console.WriteLine($"OmniLightOuterRange: {OmniOuterRange}");
                }
            }
        }
Esempio n. 14
0
            public static object ReadByType(ExtendedBinaryReader reader, ArgumentType type)
            {
                switch (type)
                {
                case AT_Bool:
                    return(reader.ReadBoolean());

                case AT_Byte:
                    return(reader.ReadByte());

                case AT_Int16:
                    return(reader.ReadInt16());

                case AT_Int32:
                    return(reader.ReadInt32());

                case AT_Float:
                    return(reader.ReadSingle());

                case AT_String:
                    return(reader.ReadStringElsewhere());

                case AT_StringPtr:
                    return(reader.ReadNullTerminatedStringPointer());

                case AT_CodePointer:
                    return(reader.ReadInt32());

                case AT_DataReference:
                    return(reader.ReadUInt32());

                case AT_DataBlock:
                    long position = reader.ReadUInt32();
                    long length   = reader.ReadUInt32();
                    if (reader.Offset > position)
                    {
                        reader.Offset = (uint)position;
                    }
                    return(new StreamBlock(position, length));

                default:
                    return(null);
                }
            }
Esempio n. 15
0
        protected virtual CharacterInfo[] GetFontTable()
        {
            var result = new CharacterInfo[256];

            using (var fs = new FileStream(Path, FileMode.Open))
                using (var input = new ExtendedBinaryReader(fs, FileEncoding, Endianness.LittleEndian))
                {
                    input.Seek(FontTableOffset, SeekOrigin.Begin);

                    for (var i = 0; i < 256; i++)
                    {
                        var tl = input.ReadSingle();
                        var tr = input.ReadSingle();
                        var ml = input.ReadSingle();
                        var mr = input.ReadSingle();
                        var bl = input.ReadSingle();
                        var br = input.ReadSingle();
                        result[i] = new CharacterInfo((byte)i)
                        {
                            OriginalData =
                            {
                                [0] = tl,
                                [1] = tr,
                                [2] = ml,
                                [3] = mr,
                                [4] = bl,
                                [5] = br
                            },
                            Data =
                            {
                                [0] = tl,
                                [1] = tr,
                                [2] = ml,
                                [3] = mr,
                                [4] = bl,
                                [5] = br
                            }
                        };
                    }
                }

            LoadFontTableChanges(result);

            for (var i = 0; i < 256; i++)
            {
                result[i].SetLoadedData();
                result[i].PropertyChanged += SubtitlePropertyChanged;
            }

            return(result);
        }
Esempio n. 16
0
        public static void LoadLight(string filePath)
        {
            using (var fileStream = File.OpenRead(filePath))
            {
                var  reader              = new ExtendedBinaryReader(fileStream, true);
                uint fileSize            = reader.ReadUInt32();
                uint rootNodeType        = reader.ReadUInt32();
                uint finalTableOffset    = reader.ReadUInt32();
                uint rootNodeOffset      = reader.ReadUInt32();
                uint finalTableOffsetAbs = reader.ReadUInt32();
                uint padding             = reader.ReadUInt32();
                lightType = (LightType)reader.ReadUInt32();
                XPos      = reader.ReadSingle();
                YPos      = reader.ReadSingle();
                ZPos      = reader.ReadSingle();
                ColorR    = reader.ReadSingle();
                ColorG    = reader.ReadSingle();
                ColorB    = reader.ReadSingle();

                // Print out Light information
                Console.WriteLine($"Light type: {lightType}");
                Console.WriteLine("");
                Console.WriteLine($"ColorR is {ColorR}," + $" It should Be {ColorR/10000} after re-saving");
                Console.WriteLine($"ColorG is {ColorG}," + $" It should Be {ColorG/10000} after re-saving");
                Console.WriteLine($"ColorB is {ColorB}," + $" It should Be {ColorB/10000} after re-saving");
                Console.WriteLine("");
                // Read Omni-Specific Values if present.
                if (lightType == LightType.Omni)
                {
                    Unknown1       = reader.ReadUInt32();
                    Unknown2       = reader.ReadUInt32();
                    Unknown3       = reader.ReadUInt32();
                    OmniInnerRange = reader.ReadSingle();
                    OmniOuterRange = reader.ReadSingle();
                }
            }
        }
Esempio n. 17
0
        public NXOB ReadNodes(ExtendedBinaryReader reader, long pos)
        {
            /*
             * Sonic 4 Decompilation Ref
             * public NNS_NODE( AppMain.NNS_NODE node )
             * {
             *  this.fType = node.fType;
             *  this.iMatrix = node.iMatrix;
             *  this.iParent = node.iParent;
             *  this.iChild = node.iChild;
             *  this.iSibling = node.iSibling;
             *  this.Translation.Assign( node.Translation );
             *  this.Rotation = node.Rotation;
             *  this.Scaling.Assign( node.Scaling );
             *  this.InvInitMtx.Assign( node.InvInitMtx );
             *  this.Center.Assign( node.Center );
             *  this.Radius = node.Radius;
             *  this.User = node.User;
             *  this.SIIKBoneLength = node.SIIKBoneLength;
             *  this.BoundingBoxY = node.BoundingBoxY;
             *  this.BoundingBoxZ = node.BoundingBoxZ;
             * }
             */
            ObjectList = new NXOB()
            {
                ObjectList = new string(reader.ReadChars(4)),
                NodeLength = reader.ReadUInt32()
            };

            pos = reader.BaseStream.Position; //Save Position
            reader.JumpTo(reader.ReadUInt32(), false);
            reader.JumpAhead(0x10);

            //Variable Names Copy & Pasted from MaxScript
            var TexElmTotal  = reader.ReadUInt32();
            var TexElmOffset = reader.ReadUInt32();

            var VertGroupTotal  = reader.ReadUInt32();
            var VertGroupOffset = reader.ReadUInt32();

            var PolyElmTotal  = reader.ReadUInt32();
            var PolyElmOffset = reader.ReadUInt32();

            //Nodes
            var NodeTotal     = reader.ReadUInt32();
            var UnknownCount1 = reader.ReadUInt32(); //Count of SOMETHING?
            var NodeOffset    = reader.ReadUInt32();

            var UnknownCount2 = reader.ReadUInt32(); //MaxScript calls this NodeTotal, but I'm sure what they call BoneTotal is actually NodeTotal? Seems to be a Count of something
            var LinkTotal     = reader.ReadUInt32();
            var LinkOffset    = reader.ReadUInt32();
            var UnknownCount3 = reader.ReadUInt32(); //Count of SOMETHING?

            //NNS_NODE
            reader.JumpTo(NodeOffset, false);
            for (int i = 0; i < NodeTotal; i++)
            {
                Node node = new Node();
                node.NODE_TYPE    = reader.ReadUInt32();
                node.NODE_MATRIX  = reader.ReadUInt16();
                node.NODE_PARENT  = reader.ReadUInt16();
                node.NODE_CHILD   = reader.ReadUInt16();
                node.NODE_SIBLING = reader.ReadUInt16();

                for (int n = 0; n < 3; n++)
                {
                    node.NODE_TRN.Add(reader.ReadSingle());
                }

                for (int n = 0; n < 3; n++)
                {
                    node.NODE_ROT.Add(reader.ReadSingle());
                }

                for (int n = 0; n < 3; n++)
                {
                    node.NODE_SCL.Add(reader.ReadSingle());
                }

                for (int n = 0; n < 16; n++)
                {
                    node.NODE_INVINIT_MTX.Add(reader.ReadSingle());
                }

                for (int n = 0; n < 3; n++)
                {
                    node.NODE_CENTER.Add(reader.ReadSingle());
                }

                node.NODE_RADIUS = reader.ReadSingle();
                node.NODE_USER   = reader.ReadUInt32();
                node.NODE_RSV0   = reader.ReadUInt32();
                node.NODE_RSV1   = reader.ReadUInt32();
                node.NODE_RSV2   = reader.ReadUInt32();
                ObjectList.Nodes.Add(node);
            }

            reader.JumpTo(TexElmOffset, false);
            var Unknown1 = reader.ReadUInt32(); //Assume this is a count???

            reader.JumpTo(reader.ReadUInt32(), false);

            return(ObjectList);
        }
Esempio n. 18
0
        public NinjaObject ReadNinjaObject(ExtendedBinaryReader reader, long pos)
        {
            NinjaObject = new NinjaObject()
            {
                NodeName = new string(reader.ReadChars(4))
            };
            uint NodeLength = reader.ReadUInt32();

            pos = reader.BaseStream.Position; //Save Position
            uint NodeOffset = reader.ReadUInt32();

            reader.JumpTo(NodeOffset, false);

            NinjaObject.ObjectCenter = reader.ReadVector3();
            NinjaObject.ObjectRadius = reader.ReadSingle();
            uint ObjectMaterialCount   = reader.ReadUInt32();
            uint ObjectMaterialOffset  = reader.ReadUInt32();
            uint ObjectVTXCount        = reader.ReadUInt32();
            uint ObjectVTXOffset       = reader.ReadUInt32();
            uint ObjectPrimitiveCount  = reader.ReadUInt32();
            uint ObjectPrimitiveOffset = reader.ReadUInt32();
            uint ObjectNodeCount       = reader.ReadUInt32();

            NinjaObject.ObjectMaxNodeDepth = reader.ReadUInt32();
            uint ObjectNodeOffset = reader.ReadUInt32();

            NinjaObject.ObjectMTXPAL = reader.ReadUInt32();
            uint ObjectSubObjectCount  = reader.ReadUInt32();
            uint ObjectSubObjectOffset = reader.ReadUInt32();

            NinjaObject.ObjectTextureCount = reader.ReadUInt32();

            //Materials
            reader.JumpTo(ObjectMaterialOffset, false);
            for (int i = 0; i < ObjectMaterialCount; i++)
            {
                //TO-DO: Figure out how all this fits together
                NinjaObjectMaterial ObjectMaterial = new NinjaObjectMaterial()
                {
                    MaterialType = reader.ReadUInt32()
                };
                uint MaterialOffset = reader.ReadUInt32();
                long currentPos     = reader.BaseStream.Position; //Save Position
                reader.JumpTo(MaterialOffset, false);

                ObjectMaterial.MaterialFlags = reader.ReadUInt32();
                ObjectMaterial.User          = reader.ReadUInt32();
                uint MaterialColourOffset  = reader.ReadUInt32();
                uint MaterialLogicOffset   = reader.ReadUInt32();
                uint MaterialTexDescOffset = reader.ReadUInt32();

                reader.JumpTo(MaterialColourOffset, false);
                ObjectMaterial.MaterialDiffuse  = reader.ReadVector4();
                ObjectMaterial.MaterialAmbient  = reader.ReadVector4();
                ObjectMaterial.MaterialSpecular = reader.ReadVector4();
                ObjectMaterial.MaterialEmissive = reader.ReadVector4();
                ObjectMaterial.MaterialPower    = reader.ReadSingle();

                reader.JumpTo(MaterialLogicOffset, false);
                ObjectMaterial.MaterialBlendenable   = reader.ReadUInt32();
                ObjectMaterial.MaterialSRCBlend      = reader.ReadUInt32();
                ObjectMaterial.MaterialDSTBlend      = reader.ReadUInt32();
                ObjectMaterial.MaterialBlendFactor   = reader.ReadUInt32();
                ObjectMaterial.MaterialBlendOP       = reader.ReadUInt32();
                ObjectMaterial.MaterialLogicOP       = reader.ReadUInt32();
                ObjectMaterial.MaterialAlphaEnable   = reader.ReadUInt32();
                ObjectMaterial.MaterialAlphaFunction = reader.ReadUInt32();
                ObjectMaterial.MaterialAlphaRef      = reader.ReadUInt32();
                ObjectMaterial.MaterialZCompenable   = reader.ReadUInt32();
                ObjectMaterial.MaterialZFunction     = reader.ReadUInt32();
                ObjectMaterial.MaterialZUpdateEnable = reader.ReadUInt32();

                reader.JumpTo(MaterialTexDescOffset, false);
                ObjectMaterial.TextureTexMapType  = reader.ReadUInt32();
                ObjectMaterial.TextureID          = reader.ReadUInt32();
                ObjectMaterial.TextureOffset      = reader.ReadVector2();
                ObjectMaterial.TextureBlend       = reader.ReadSingle();
                ObjectMaterial.TextureInfoPTR     = reader.ReadUInt32();
                ObjectMaterial.TextureMinFilter   = reader.ReadUInt32();
                ObjectMaterial.TextureMagFilter   = reader.ReadUInt32();
                ObjectMaterial.TextureMipMapBias  = reader.ReadSingle();
                ObjectMaterial.TextureMaxMipLevel = reader.ReadUInt32();

                reader.JumpTo(currentPos, true);
                NinjaObject.ObjectMaterialList.Add(ObjectMaterial);
            }

            //Vertexes
            reader.JumpTo(ObjectVTXOffset, false);
            for (int i = 0; i < ObjectVTXCount; i++)
            {
                NinjaObjectVertex ObjectVertex = new NinjaObjectVertex()
                {
                    Type = reader.ReadUInt32()
                };
                uint VTXOffset  = reader.ReadUInt32();
                long currentPos = reader.BaseStream.Position; //Save Position

                reader.JumpTo(VTXOffset, false);
                ObjectVertex.VTXFormat = reader.ReadUInt32();
                ObjectVertex.VTXFVF    = reader.ReadUInt32();
                ObjectVertex.VTXSize   = reader.ReadUInt32();
                uint VTXNumber     = reader.ReadUInt32();
                uint VTXListOffset = reader.ReadUInt32();
                ObjectVertex.VTXBlendNum = reader.ReadUInt32();
                uint VTXMTXOffset = reader.ReadUInt32();
                ObjectVertex.VTXHDRCommon = reader.ReadUInt32();
                ObjectVertex.VTXHDRData   = reader.ReadUInt32();
                ObjectVertex.VTXHDRLock   = reader.ReadUInt32();

                reader.JumpTo(VTXListOffset, false);
                for (int v = 0; v < VTXNumber; v++)
                {
                    NinjaObjectVertexList Vertex = new NinjaObjectVertexList();
                    switch (ObjectVertex.VTXSize)
                    {
                    //Any ones other than 52 & 76 are probably wrong here, as they're not in the XTO and are instead based on the MaxScript
                    //This is such a mess
                    case 20:
                        Vertex.Position = reader.ReadVector3();
                        Vertex.ST0      = reader.ReadVector2();
                        ObjectVertex.Vertexes.Add(Vertex);
                        break;

                    case 24:
                        Vertex.Position = reader.ReadVector3();
                        Vertex.RGBA8888 = reader.ReadBytes(4);
                        Vertex.ST0      = reader.ReadVector2();
                        ObjectVertex.Vertexes.Add(Vertex);
                        break;

                    case 28:
                        Vertex.Position = reader.ReadVector3();
                        Vertex.Normals  = reader.ReadVector3();
                        Vertex.RGBA8888 = reader.ReadBytes(4);
                        ObjectVertex.Vertexes.Add(Vertex);
                        break;

                    case 32:
                        Vertex.Position = reader.ReadVector3();
                        Vertex.Normals  = reader.ReadVector3();
                        Vertex.ST0      = reader.ReadVector2();
                        ObjectVertex.Vertexes.Add(Vertex);
                        break;

                    case 36:
                        Vertex.Position = reader.ReadVector3();
                        Vertex.Normals  = reader.ReadVector3();
                        Vertex.RGBA8888 = reader.ReadBytes(4);
                        Vertex.ST0      = reader.ReadVector2();
                        ObjectVertex.Vertexes.Add(Vertex);
                        break;

                    case 44:
                        Vertex.Position  = reader.ReadVector3();
                        Vertex.Normals   = reader.ReadVector3();
                        Vertex.RGBA8888  = reader.ReadBytes(4);
                        Vertex.ST0       = reader.ReadVector2();
                        Vertex.UnknownV2 = reader.ReadVector2();
                        ObjectVertex.Vertexes.Add(Vertex);
                        break;

                    case 48:
                        Vertex.Position = reader.ReadVector3();
                        Vertex.Weight3  = reader.ReadVector3();
                        Vertex.Normals  = reader.ReadVector3();
                        Vertex.RGBA8888 = reader.ReadBytes(4);
                        Vertex.ST0      = reader.ReadVector2();
                        ObjectVertex.Vertexes.Add(Vertex);
                        break;

                    case 52:
                        Vertex.Position = reader.ReadVector3();
                        Vertex.Weight3  = reader.ReadVector3();
                        Vertex.MTXIDX   = reader.ReadBytes(4);
                        Vertex.Normals  = reader.ReadVector3();
                        Vertex.RGBA8888 = reader.ReadBytes(4);
                        Vertex.ST0      = reader.ReadVector2();
                        ObjectVertex.Vertexes.Add(Vertex);
                        break;

                    case 60:
                        Vertex.Position = reader.ReadVector3();
                        Vertex.Weight3  = reader.ReadVector3();
                        Vertex.Normals  = reader.ReadVector3();
                        Vertex.Tan      = reader.ReadVector3();
                        Vertex.BNormal  = reader.ReadVector3();
                        ObjectVertex.Vertexes.Add(Vertex);
                        break;

                    case 72:
                        Vertex.Position = reader.ReadVector3();
                        Vertex.Weight3  = reader.ReadVector3();
                        Vertex.MTXIDX   = reader.ReadBytes(4);
                        Vertex.Normals  = reader.ReadVector3();
                        Vertex.ST0      = reader.ReadVector2();
                        Vertex.Tan      = reader.ReadVector3();
                        Vertex.BNormal  = reader.ReadVector3();
                        ObjectVertex.Vertexes.Add(Vertex);
                        break;

                    case 76:
                        Vertex.Position = reader.ReadVector3();
                        Vertex.Weight3  = reader.ReadVector3();
                        Vertex.MTXIDX   = reader.ReadBytes(4);
                        Vertex.Normals  = reader.ReadVector3();
                        Vertex.RGBA8888 = reader.ReadBytes(4);
                        Vertex.ST0      = reader.ReadVector2();
                        Vertex.Tan      = reader.ReadVector3();
                        Vertex.BNormal  = reader.ReadVector3();
                        ObjectVertex.Vertexes.Add(Vertex);
                        break;

                    default:
                        Console.WriteLine($"Vertex Size of {ObjectVertex.VTXSize} not handled!");
                        continue;
                    }
                }

                if (VTXMTXOffset != 0)
                {
                    reader.JumpTo(VTXMTXOffset, false);
                    ObjectVertex.VTXMTX = reader.ReadInt32();
                }

                reader.JumpTo(currentPos, true);
                NinjaObject.ObjectVertexList.Add(ObjectVertex);
            }

            reader.JumpTo(ObjectPrimitiveOffset, false);
            for (int i = 0; i < ObjectPrimitiveCount; i++)
            {
                NinjaObjectPrimitive ObjectPrimitive = new NinjaObjectPrimitive()
                {
                    Type = reader.ReadUInt32()
                };
                uint PrimitiveListOffset = reader.ReadUInt32();
                long currentPos          = reader.BaseStream.Position; //Save Position

                reader.JumpTo(PrimitiveListOffset, false);
                ObjectPrimitive.Format = reader.ReadUInt32();
                ObjectPrimitive.Index  = reader.ReadUInt32();
                ObjectPrimitive.Strip  = reader.ReadUInt32();
                uint LengthOffset = reader.ReadUInt32();
                uint IndexOffset  = reader.ReadUInt32();
                ObjectPrimitive.IndexBuf = reader.ReadUInt32();

                reader.JumpTo(LengthOffset, false);
                ObjectPrimitive.IndexLength = reader.ReadUInt16(); //May be the same as Index all the time???

                reader.JumpTo(IndexOffset, false);
                for (int v = 0; v < ObjectPrimitive.Index; v++)
                {
                    ObjectPrimitive.VertexIndexList.Add(reader.ReadUInt16());
                }

                reader.JumpTo(currentPos, true);
                NinjaObject.ObjectPrimitiveList.Add(ObjectPrimitive);
            }

            reader.JumpTo(ObjectNodeOffset, false);
            for (int i = 0; i < ObjectNodeCount; i++)
            {
                NinjaObjectNodeList Node = new NinjaObjectNodeList()
                {
                    Type      = reader.ReadUInt32(),
                    Matrix    = reader.ReadUInt16(),
                    Parent    = reader.ReadUInt16(),
                    Child     = reader.ReadUInt16(),
                    Sibling   = reader.ReadUInt16(),
                    Transform = reader.ReadVector3(),
                    Rotation  = reader.ReadVector3(),
                    Scale     = reader.ReadVector3()
                };
                for (int v = 0; v < 16; v++)
                {
                    Node.Invinit.Add(reader.ReadSingle());
                }
                Node.Center = reader.ReadVector3();
                Node.User   = reader.ReadUInt32();
                Node.RSV0   = reader.ReadUInt32();
                Node.RSV1   = reader.ReadUInt32();
                Node.RSV2   = reader.ReadUInt32();
                reader.JumpAhead(0x4);
                NinjaObject.ObjectNodeList.Add(Node);
            }

            reader.JumpTo(ObjectSubObjectOffset, false);
            for (int i = 0; i < ObjectSubObjectCount; i++)
            {
                uint Type           = reader.ReadUInt32();
                uint NMSST          = reader.ReadUInt32();
                uint MSSTOffset     = reader.ReadUInt32();
                uint Textures       = reader.ReadUInt32();
                uint TexturesOffset = reader.ReadUInt32();
                long currentPos     = reader.BaseStream.Position; //Save Position

                reader.JumpTo(MSSTOffset, false);
                for (int v = 0; v < NMSST; v++)
                {
                    NinjaObjectSubObject SubObject = new NinjaObjectSubObject()
                    {
                        Center     = reader.ReadVector3(),
                        Radius     = reader.ReadSingle(),
                        Node       = reader.ReadUInt32(),
                        Matrix     = reader.ReadUInt32(),
                        Material   = reader.ReadUInt32(),
                        VertexList = reader.ReadUInt32(),
                        PrimList   = reader.ReadUInt32(),
                        ShaderList = reader.ReadUInt32()
                    };
                    NinjaObject.ObjectSubObjectList.Add(SubObject);
                }

                reader.JumpTo(currentPos, true);
            }

            reader.JumpTo(pos, true);
            reader.JumpAhead(NodeLength);
            return(NinjaObject);
        }
Esempio n. 19
0
 public override object Read(ExtendedBinaryReader reader) => reader.ReadSingle();
Esempio n. 20
0
        private static SetObject ReadObject(ExtendedBinaryReader reader,
                                            SetObjectType objTemplate, string objType, SOBJType type,
                                            bool rawDataMode = false) // true = full, false = only remaining bytes
        {
            // For some reason these separate values are saved as one uint rather than two ushorts.
            // Because of this, the values are in a different order depending on endianness, and
            // this is the easiest known way to read them.
            uint   unknownValue = reader.ReadUInt32();
            ushort unknown1     = (ushort)((unknownValue >> 16) & 0xFFFF);
            ushort objID        = (ushort)(unknownValue & 0xFFFF);

            var obj = new SetObject()
            {
                ObjectType = objType,
                ObjectID   = objID
            };

            uint  unknown2 = reader.ReadUInt32();
            uint  unknown3 = reader.ReadUInt32();
            float unknown4 = reader.ReadSingle();

            float rangeIn          = reader.ReadSingle();
            float rangeOut         = reader.ReadSingle();
            uint  parent           = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0;
            uint  transformsOffset = reader.ReadUInt32();

            uint transformCount = reader.ReadUInt32();
            uint unknown5       = reader.ReadUInt32();
            uint unknown6       = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0;
            uint unknown7       = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0;

            // Call me crazy, but I have a weird feeling these values aren't JUST padding
            if (unknown3 != 0 || unknown5 != 0 || unknown6 != 0 || unknown7 != 0)
            {
                Console.WriteLine("WARNING: Not padding?! ({0},{1},{2},{3})",
                                  unknown3, unknown5, unknown6, unknown7);
            }

            // Add custom data to object
            obj.CustomData.Add("Unknown1", new SetObjectParam(typeof(ushort), unknown1));
            obj.CustomData.Add("Unknown2", new SetObjectParam(typeof(uint), unknown2));
            obj.CustomData.Add("Unknown3", new SetObjectParam(typeof(uint), unknown3));
            obj.CustomData.Add("Unknown4", new SetObjectParam(typeof(float), unknown4));
            obj.CustomData.Add("RangeIn", new SetObjectParam(typeof(float), rangeIn));
            obj.CustomData.Add("RangeOut", new SetObjectParam(typeof(float), rangeOut));

            if (type == SOBJType.LostWorld)
            {
                obj.CustomData.Add("Parent", new SetObjectParam(typeof(uint), parent));
            }

            // Skip loading parameters if template doesn't exist
            if (objTemplate != null)
            {
                // Get Raw Byte Length
                var  rawDataLenExtra = objTemplate.GetExtra("RawByteLength");
                long paramBegin      = reader.BaseStream.Position;
                int  rawLength       = 0;

                if (rawDataLenExtra != null &&
                    !string.IsNullOrEmpty(rawDataLenExtra.Value))
                {
                    int.TryParse(rawDataLenExtra.Value, out rawLength);
                }

                // Read all the data then return to beginning
                if (rawDataMode == true && rawLength != 0)
                {
                    obj.CustomData.Add("RawParamData", new SetObjectParam(typeof(byte[]),
                                                                          reader.ReadBytes(rawLength)));
                    reader.JumpTo(paramBegin);
                }

                // Parameters
                foreach (var param in objTemplate.Parameters)
                {
                    // For compatibility with SonicGlvl templates.
                    if (param.Name == "Unknown1" || param.Name == "Unknown2" ||
                        param.Name == "Unknown3" || param.Name == "RangeIn" ||
                        param.Name == "RangeOut" || param.Name == "Parent")
                    {
                        continue;
                    }

                    // Read Special Types/Fix Padding
                    if (param.DataType == typeof(uint[]))
                    {
                        // Data Info
                        reader.FixPadding(4);
                        uint arrOffset  = reader.ReadUInt32();
                        uint arrLength  = reader.ReadUInt32();
                        uint arrUnknown = reader.ReadUInt32();
                        long curPos     = reader.BaseStream.Position;

                        // Data
                        var arr = new uint[arrLength];
                        reader.JumpTo(arrOffset, false);

                        for (uint i = 0; i < arrLength; ++i)
                        {
                            arr[i] = reader.ReadUInt32();
                        }

                        obj.Parameters.Add(new SetObjectParam(param.DataType, arr));
                        reader.BaseStream.Position = curPos;
                        continue;
                    }
                    else if (param.DataType == typeof(string))
                    {
                        // Data Info
                        uint   strOffset  = reader.ReadUInt32();
                        uint   strUnknown = reader.ReadUInt32();
                        string str        = null;

                        // Data
                        if (strOffset != 0)
                        {
                            long curPos = reader.BaseStream.Position;
                            reader.JumpTo(strOffset, false);

                            str = reader.ReadNullTerminatedString();
                            reader.BaseStream.Position = curPos;
                        }

                        obj.Parameters.Add(new SetObjectParam(param.DataType, str));
                        continue;
                    }
                    else if (param.DataType == typeof(float) ||
                             param.DataType == typeof(int) || param.DataType == typeof(uint))
                    {
                        reader.FixPadding(4);
                    }
                    else if (type == SOBJType.LostWorld && param.DataType == typeof(Vector3))
                    {
                        reader.FixPadding(16);
                    }

                    // Read Data
                    var objParam = new SetObjectParam(param.DataType,
                                                      reader.ReadByType(param.DataType));
                    obj.Parameters.Add(objParam);
                }

                if (rawDataMode == false)
                {
                    long knownParamLength = (reader.BaseStream.Position - paramBegin);
                    long remainingBytes   = (rawLength - knownParamLength);

                    obj.CustomData.Add("RawParamData", new SetObjectParam(typeof(byte[]),
                                                                          reader.ReadBytes((int)remainingBytes)));
                }
            }

            // Transforms
            uint childCount = transformCount - 1;

            obj.Children = new SetObjectTransform[childCount];
            reader.JumpTo(transformsOffset, false);

            obj.Transform = ReadTransform(reader, type == SOBJType.LostWorld);
            for (uint i = 0; i < childCount; ++i)
            {
                obj.Children[i] = ReadTransform(reader,
                                                type == SOBJType.LostWorld);
            }

            return(obj);
        }
Esempio n. 21
0
 public override void Deserialize(ExtendedBinaryReader reader, Action <float> valueFixup)
 {
     valueFixup(reader.ReadSingle());
 }
Esempio n. 22
0
        /// <summary>
        /// Reads a SEAnim from a stream
        /// </summary>
        /// <param name="Stream">The stream to read from</param>
        /// <returns>A SEAnim if successful, otherwise throws an error and returns null</returns>
        public static SEModel Read(Stream Stream)
        {
            // Create a new model
            var model = new SEModel();

            // Setup a new reader
            using (ExtendedBinaryReader readFile = new ExtendedBinaryReader(Stream))
            {
                // Magic
                var Magic = readFile.ReadChars(7);
                // Version
                var Version = readFile.ReadInt16();
                // Header size
                var HeaderSize = readFile.ReadInt16();
                // Check magic
                if (!Magic.SequenceEqual(new char[] { 'S', 'E', 'M', 'o', 'd', 'e', 'l' }))
                {
                    // Bad file
                    throw new Exception("Bad SEModel file, magic was invalid");
                }
                // Data present flags
                var DataPresentFlags = readFile.ReadByte();
                // Bone data present flags
                var BoneDataPresentFlags = readFile.ReadByte();
                // Mesh data present flags
                var MeshDataPresentFlags = readFile.ReadByte();

                // Read counts
                var BoneCount = readFile.ReadInt32();
                var MeshCount = readFile.ReadInt32();
                var MatCount  = readFile.ReadInt32();

                // Skip 3 reserved bytes
                readFile.BaseStream.Position += 3;

                // Read bone tag names
                List <string> BoneNames = new List <string>();
                // Loop
                for (int i = 0; i < BoneCount; i++)
                {
                    BoneNames.Add(readFile.ReadNullTermString());
                }

                // Loop and read bones
                for (int i = 0; i < BoneCount; i++)
                {
                    // Read bone flags (unused)
                    var BoneFlags = readFile.ReadByte();

                    // Read bone index
                    var ParentIndex = readFile.ReadInt32();

                    // Check for global matricies
                    Vector3    GlobalPosition = Vector3.Zero;
                    Quaternion GlobalRotation = Quaternion.Identity;
                    // Check
                    if (Convert.ToBoolean(BoneDataPresentFlags & (byte)SEModel_BoneDataPresenceFlags.SEMODEL_PRESENCE_GLOBAL_MATRIX))
                    {
                        GlobalPosition = new Vector3(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                        GlobalRotation = new Quaternion(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                    }

                    // Check for local matricies
                    Vector3    LocalPosition = Vector3.Zero;
                    Quaternion LocalRotation = Quaternion.Identity;
                    // Check
                    if (Convert.ToBoolean(BoneDataPresentFlags & (byte)SEModel_BoneDataPresenceFlags.SEMODEL_PRESENCE_LOCAL_MATRIX))
                    {
                        LocalPosition = new Vector3(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                        LocalRotation = new Quaternion(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                    }

                    // Check for scales
                    Vector3 Scale = Vector3.One;
                    // Check
                    if (Convert.ToBoolean(BoneDataPresentFlags & (byte)SEModel_BoneDataPresenceFlags.SEMODEL_PRESENCE_SCALES))
                    {
                        Scale = new Vector3(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                    }

                    // Add the bone
                    model.AddBone(BoneNames[i], ParentIndex, GlobalPosition, GlobalRotation, LocalPosition, LocalRotation, Scale);
                }

                // Loop and read meshes
                for (int i = 0; i < MeshCount; i++)
                {
                    // Make a new submesh
                    var mesh = new SEModelMesh();

                    // Read mesh flags (unused)
                    var MeshFlags = readFile.ReadByte();

                    // Read counts
                    var MatIndiciesCount      = readFile.ReadByte();
                    var MaxSkinInfluenceCount = readFile.ReadByte();
                    var VertexCount           = readFile.ReadInt32();
                    var FaceCount             = readFile.ReadInt32();

                    // Loop and read positions
                    for (int v = 0; v < VertexCount; v++)
                    {
                        mesh.AddVertex(new SEModelVertex()
                        {
                            Position = new Vector3(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle())
                        });
                    }

                    // Read uvlayers
                    if (Convert.ToBoolean(MeshDataPresentFlags & (byte)SEModel_MeshDataPresenceFlags.SEMODEL_PRESENCE_UVSET))
                    {
                        for (int v = 0; v < VertexCount; v++)
                        {
                            for (int l = 0; l < MatIndiciesCount; l++)
                            {
                                mesh.Verticies[v].UVSets.Add(new Vector2(readFile.ReadSingle(), readFile.ReadSingle()));
                            }
                        }
                    }

                    // Read normals
                    if (Convert.ToBoolean(MeshDataPresentFlags & (byte)SEModel_MeshDataPresenceFlags.SEMODEL_PRESENCE_NORMALS))
                    {
                        // Loop and read vertex normals
                        for (int v = 0; v < VertexCount; v++)
                        {
                            mesh.Verticies[v].VertexNormal = new Vector3(readFile.ReadSingle(), readFile.ReadSingle(), readFile.ReadSingle());
                        }
                    }

                    // Read colors
                    if (Convert.ToBoolean(MeshDataPresentFlags & (byte)SEModel_MeshDataPresenceFlags.SEMODEL_PRESENCE_COLOR))
                    {
                        // Loop and read colors
                        for (int v = 0; v < VertexCount; v++)
                        {
                            mesh.Verticies[v].VertexColor = new Color(readFile.ReadByte(), readFile.ReadByte(), readFile.ReadByte(), readFile.ReadByte());
                        }
                    }

                    // Read weights
                    if (Convert.ToBoolean(MeshDataPresentFlags & (byte)SEModel_MeshDataPresenceFlags.SEMODEL_PRESENCE_WEIGHTS))
                    {
                        for (int v = 0; v < VertexCount; v++)
                        {
                            // Read IDs and Values
                            for (int l = 0; l < MaxSkinInfluenceCount; l++)
                            {
                                if (BoneCount <= 0xFF)
                                {
                                    mesh.Verticies[v].Weights.Add(new SEModelWeight()
                                    {
                                        BoneIndex = readFile.ReadByte(), BoneWeight = readFile.ReadSingle()
                                    });
                                }
                                else if (BoneCount <= 0xFFFF)
                                {
                                    mesh.Verticies[v].Weights.Add(new SEModelWeight()
                                    {
                                        BoneIndex = readFile.ReadUInt16(), BoneWeight = readFile.ReadSingle()
                                    });
                                }
                                else
                                {
                                    mesh.Verticies[v].Weights.Add(new SEModelWeight()
                                    {
                                        BoneIndex = readFile.ReadUInt32(), BoneWeight = readFile.ReadSingle()
                                    });
                                }
                            }
                        }
                    }

                    // Loop and read faces
                    for (int f = 0; f < FaceCount; f++)
                    {
                        if (VertexCount <= 0xFF)
                        {
                            mesh.AddFace(readFile.ReadByte(), readFile.ReadByte(), readFile.ReadByte());
                        }
                        else if (VertexCount <= 0xFFFF)
                        {
                            mesh.AddFace(readFile.ReadUInt16(), readFile.ReadUInt16(), readFile.ReadUInt16());
                        }
                        else
                        {
                            mesh.AddFace(readFile.ReadUInt32(), readFile.ReadUInt32(), readFile.ReadUInt32());
                        }
                    }

                    // Read material reference indicies
                    for (int f = 0; f < MatIndiciesCount; f++)
                    {
                        mesh.AddMaterialIndex(readFile.ReadInt32());
                    }

                    // Add the mesh
                    model.AddMesh(mesh);
                }

                // Loop and read materials
                for (int m = 0; m < MatCount; m++)
                {
                    var mat = new SEModelMaterial();

                    // Read the name
                    mat.Name = readFile.ReadNullTermString();
                    // Read IsSimpleMaterial
                    var IsSimpleMaterial = readFile.ReadBoolean();

                    // Read the material
                    if (IsSimpleMaterial)
                    {
                        mat.MaterialData = new SEModelSimpleMaterial()
                        {
                            DiffuseMap  = readFile.ReadNullTermString(),
                            NormalMap   = readFile.ReadNullTermString(),
                            SpecularMap = readFile.ReadNullTermString()
                        };
                    }

                    // Add the material
                    model.AddMaterial(mat);
                }
            }
            // Return result
            return(model);
        }
Esempio n. 23
0
 public override void Read(ExtendedBinaryReader reader, Action <float> synchronizationCallback)
 {
     synchronizationCallback(reader.ReadSingle());
 }
Esempio n. 24
0
        // Methods
        public override void Load(Stream fileStream)
        {
            // Header
            var  reader = new ExtendedBinaryReader(fileStream);
            uint header = reader.ReadUInt32();

            uint sig     = (header & 0xFFFFFF);
            byte version = (byte)((header & 0xFF000000) >> 24);

            if (sig != Signature)
            {
                throw new InvalidSignatureException("MDL",
                                                    Encoding.ASCII.GetString(BitConverter.GetBytes(sig), 0, 3));
            }

            if (version > Version)
            {
                throw new NotSupportedException(
                          $"Cannot read version {version} of the format.");
            }

            // Meshes
            Mesh mesh;
            uint len, i, i2;
            uint meshCount = reader.ReadUInt32();
            byte indicesType;

            for (i = 0; i < meshCount; ++i)
            {
                // Vertex Data
                mesh            = new Mesh();
                len             = reader.ReadUInt32();
                mesh.VertexData = new float[len];

                for (i2 = 0; i2 < len; ++i2)
                {
                    mesh.VertexData[i2] = reader.ReadSingle();
                }

                // Triangle Indices
                len         = reader.ReadUInt32();
                indicesType = (byte)((len & 0xC0000000) >> 30);
                len        &= 0x3FFFFFFF;

                mesh.Triangles = new uint[len];
                for (i2 = 0; i2 < len; ++i2)
                {
                    // 0 = 32-bit, 1 = 16-bit, 2 = 8-bit
                    switch (indicesType)
                    {
                    case 0:
                    default:
                        mesh.Triangles[i2] = reader.ReadUInt32();
                        continue;

                    case 1:
                        mesh.Triangles[i2] = reader.ReadUInt16();
                        continue;

                    case 2:
                        mesh.Triangles[i2] = reader.ReadByte();
                        continue;
                    }
                }

                // Material Name
                mesh.MaterialName = reader.ReadString();
                Meshes.Add(mesh);
            }
        }