예제 #1
0
        public override void Read(RW4Model m, RW4Section s, Stream r)
        {
            if (s.type_code != type_code)
            {
                throw new ModelFormatException(r, "VA000 Bad type code", s.type_code);
            }
            var section_1 = r.ReadS32();

            vertexFormatSection = section_1;
            this.unk2           = r.ReadU32();
            r.expect(0, "VA001");
            var vcount = r.ReadU32();

            r.expect(8, "VA002");

            vertexSize = r.ReadU32();

            var section_number = r.ReadS32();

            var section = m.Sections[section_number];

            section.LoadObject(m, vertices = new VertexBuffer((int)vcount), r);

            section = m.Sections[section_1];
            if (section.type_code != VertexFormat.type_code)
            {
                throw new ModelFormatException(r, "VA101 Bad section type code", section.type_code);
            }
            section.GetObject(m, r, out format); //get the stuff
        }
예제 #2
0
        public override void Read(RW4Model m, RW4Section s, Stream r)
        {
            // TODO: some files have multiple meshes referencing the same vertex and/or triangle buffers
            r.expect(40, "ME001");
            r.expect(4, "ME002");
            var tri_section = r.ReadS32();

            this.tri_count = r.ReadU32();
            r.expect(1, "ME003");
            r.expect(0, "ME004");
            r.expect(tri_count * 3, "ME005");
            r.expect(0, "ME006");
            this.vert_count = r.ReadU32();
            var vert_section = r.ReadS32();

            m.Sections[tri_section].GetObject(m, r, out triangles);
            if (triangles.triangles.Length != tri_count)
            {
                throw new ModelFormatException(r, "ME100 Triangle count mismatch", new KeyValuePair <uint, int>(tri_count, triangles.triangles.Length));
            }

            if (vert_section != 0x400000)
            {
                m.Sections[vert_section].GetObject(m, r, out vertices);
                if (vertices.vertices.Length != vert_count)
                {
                    throw new ModelFormatException(r, "ME200 Vertex count mismatch", new KeyValuePair <uint, int>(vert_count, vertices.vertices.Length));
                }
                //seperate the vertices
                Vertex previousVertex = new Vertex();
                int    element        = 0;
                for (int j = 0; j < vertices.vertices.Length; j++)
                {
                    if (previousVertex.VertexComponents != null)
                    {
                        bool isMatch = true;
                        for (int i = 0; i < vertices.vertices[j].VertexComponents.Count; i++)
                        {
                            if (vertices.vertices[j].VertexComponents[i].DeclarationType == D3DDECLTYPE.D3DDECLTYPE_D3DCOLOR)
                            {
                                if (vertices.vertices[j].VertexComponents[i].Value != previousVertex.VertexComponents[i].Value)
                                {
                                    isMatch = false;
                                }
                            }
                        }
                        if (!isMatch)
                        {
                            element++;
                        }
                    }
                    Vertex newVertex = vertices.vertices[j];
                    newVertex.Element    = element;
                    vertices.vertices[j] = newVertex;
                    previousVertex       = vertices.vertices[j];
                }

                vertices.section.obj = vertices;
            }
        }
예제 #3
0
        public override void Read(RW4Model m, RW4Section s, Stream r)
        {
            if (s.type_code != type_code)
            {
                throw new ModelFormatException(r, "TA000 Bad type code", s.type_code);
            }
            unk1 = r.ReadU32();
            r.expect(0, "TA001");
            var ind_count = r.ReadU32();

            r.expect(8, "TA002");
            r.expect(101, "TA003");
            r.expect(4, "TA004");
            var section_number = r.ReadS32();

            if (ind_count % 3 != 0)
            {
                throw new ModelFormatException(r, "TA010", ind_count);
            }
            var tri_count = ind_count / 3;

            var section = m.Sections[section_number];

            section.LoadObject(m, triangles = new Buffer <Triangle>((int)tri_count), r);
        }
예제 #4
0
 public override void Write(RW4Model m, RW4Section s, Stream w)
 {
     w.WriteU32(Size);
     if (Header != null)
     {
         w.Write(Header, 0, Header.Length);
     }
     if (VertexFormatData != null)
     {
         w.Write(VertexFormatData, 0, VertexFormatData.Length);
     }
     if (AdditionalData != null)
     {
         w.Write(AdditionalData, 0, AdditionalData.Length);
     }
     foreach (MaterialTextureReference mat in Materials)
     {
         w.WriteU32(mat.Unknown1);
         w.WriteU32(mat.Unknown2);
         w.WriteU32(mat.TextureInstanceId);
         w.WriteU32(mat.Unknown3);
         w.WriteU32(mat.Unknown4);
         w.WriteU32(mat.Unknown5);
     }
     if (Data != null)
     {
         w.Write(Data, 0, Data.Length);
     }
 }
예제 #5
0
        public void LoadObject(RW4Model model, RW4Object o, Stream r)
        {
            if (obj != null)
            {
                throw new ModelFormatException(r, "Attempt to decode section twice.", Number);
            }
            long start = r.Position;

            obj       = o;
            o.section = this;
            o.model   = model;
            r.Seek(Pos, SeekOrigin.Begin);
            obj.Read(model, this, r);
            if (r.Position != Pos + Size)
            {
                throw new ModelFormatException(r, "Section incompletely read.", Number);
            }
            var cs = obj.ComputeSize();

            if (cs != -1 && cs != Size)
            {
                throw new ModelFormatException(r, "Section Size doesn't match computed Size.", Number);
            }
            r.Seek(start, SeekOrigin.Begin);
        }
예제 #6
0
 public override void Write(RW4Model m, RW4Section s, Stream w)
 {
     for (int i = 0; i < items.Length; i++)
     {
         items[i].Write(w);
     }
 }
예제 #7
0
        public WriteableBitmap GetBitmap()
        {
            DatabaseIndex imageIndex = DatabaseManager.Instance.Indices.Find(idx => idx.InstanceId == this.TextureInstanceId && (idx.TypeId == PropertyConstants.RasterImageType || idx.TypeId == PropertyConstants.RW4ImageType));

            if (imageIndex != null)
            {
                if (imageIndex.TypeId == PropertyConstants.RasterImageType)
                {
                    using (MemoryStream imageByteStream = new MemoryStream(imageIndex.GetIndexData(true)))
                    {
                        RasterImage img = RasterImage.CreateFromStream(imageByteStream, RasterChannel.All);
                        return(img.MipMaps[0]);
                    }
                }
                else if (imageIndex.TypeId == PropertyConstants.RW4ImageType)
                {
                    using (MemoryStream imageByteStream = new MemoryStream(imageIndex.GetIndexData(true)))
                    {
                        RW4Model mod = new RW4Model();
                        mod.Read(imageByteStream);
                        RW4Section texSection = mod.Sections.First(s => s.TypeCode == SectionTypeCodes.Texture);
                        return((texSection.obj as Texture).ToImage(false));
                    }
                }
            }
            return(null);
        }
예제 #8
0
 public override void Read(RW4Model m, RW4Section s, Stream r)
 {
     if (!Relocatable())
     {
         this.required_position = r.Position;
     }
     blob = r.ReadBytes((int)s.Size);
 }
예제 #9
0
 public override void Write(RW4Model m, RW4Section s, Stream w)
 {
     if (this.required_position >= 0 && w.Position != this.required_position)
     {
         throw new ModelFormatException(w, "Unable to move Unknown2 section", null);
     }
     w.Write(blob, 0, blob.Length);
 }
예제 #10
0
 public override void Write(RW4Model m, RW4Section s, Stream w)
 {
     w.WriteU32(0x400000);
     w.WriteU32(unk1);
     w.WriteU32(mat3.section.Number);
     w.WriteU32(jointInfo.section.Number);
     w.WriteU32(mat4.section.Number);
 }
 public override void Write(RW4Model m, RW4Section s, Stream w)
 {
     w.WriteU32(mesh.section.Number);
     w.WriteU32((uint)mat.Length);
     foreach (var x in mat)
     {
         w.WriteU32(x.section.Number);
     }
 }
예제 #12
0
 public override void Write(RW4Model m, RW4Section s, Stream w)
 {
     w.Write(unk_data_1, 0, unk_data_1.Length);
     w.WriteU32(texture.section.Number);
     for (int i = 0; i < unk_data_2.Length; i++)
     {
         w.WriteS32(unk_data_2[i]);
     }
 }
예제 #13
0
 public override void Read(RW4Model m, RW4Section s, Stream r)
 {
     minx = r.ReadF32(); miny = r.ReadF32(); minz = r.ReadF32(); unk1 = r.ReadU32();
     maxx = r.ReadF32(); maxy = r.ReadF32(); maxz = r.ReadF32(); unk2 = r.ReadU32();
     if (minx > maxx || miny > maxy || minz > maxz)
     {
         throw new ModelFormatException(r, "BBOX011", null);
     }
 }
예제 #14
0
 public void Write(Stream w, RW4Model model)
 {
     w.WritePadding(Pos - w.Position);
     obj.Write(model, this, w);
     if (w.Position != Pos + Size)
     {
         throw new ModelFormatException(w, "Section incompletely written.", Number);
     }
 }
예제 #15
0
 public override void Write(RW4Model m, RW4Section s, Stream w)
 {
     w.WriteU32(unk1);
     w.WriteU32(0);
     w.WriteU32((uint)triangles.Length * 3);
     w.WriteU32(8);
     w.WriteU32(101);
     w.WriteU32(4);
     w.WriteU32(triangles.section.Number);
 }
예제 #16
0
        public ModelUnpack(Stream input, string outputPath)
        {
            var model = new RW4Model();

            model.Read(input);
            //if (model.FileType == RW4Model.FileTypes.Model)
            //     unpackModel(model, outputPath + "\\model.mesh.xml");
            // else
            unpackTexture(model, outputPath + "\\texture");
        }
예제 #17
0
 public override void Write(RW4Model m, RW4Section s, Stream w)
 {
     w.WriteU32((uint)this.vertexFormatSection);
     w.WriteU32(this.unk2);
     w.WriteU32(0);
     w.WriteU32((uint)vertices.Length);
     w.WriteU32(8);
     w.WriteU32(vertexSize);
     w.WriteU32(vertices.section.Number);
 }
예제 #18
0
 public DDSPack(string inputFileName, Stream output)
 {
     using (var src = File.OpenRead(inputFileName))
     {
         var model = new RW4Model();
         model.New();
         pack(src, model);
         model.Write(output);
     }
 }
예제 #19
0
 public void GetObject <T>(RW4Model model, Stream r, out T o)
     where T : RW4Object, new()
 {
     if (obj != null)
     {
         o = (T)obj;
         return;
     }
     o = new T();
     LoadObject(model, o, r);
 }
예제 #20
0
 public override void Read(RW4Model m, RW4Section s, Stream r)
 {
     if (s.type_code != type_code)
     {
         throw new ModelFormatException(r, "VB000 Bad type code", s.type_code);
     }
     for (int i = 0; i < items.Length; i++)
     {
         items[i].Read(r);
     }
 }
예제 #21
0
        public ModelPack(string inputFileName, Stream output)
        {
            var src_model = new OgreXmlReader(inputFileName);

            var model = new RW4Model();
            model.New();

            pack(src_model, model);

            model.Write(output);
        }
예제 #22
0
 public override void Write(RW4Model m, RW4Section s, Stream w)
 {
     w.WriteU32(textureType);
     w.WriteU32(8);
     w.WriteU32(unk1);
     w.WriteU16(width);
     w.WriteU16(height);
     w.WriteU32(mipmapInfo);
     w.WriteU32(0);
     w.WriteU32(0);
     w.WriteU32(texData.section.Number);
 }
예제 #23
0
        public override void Write(RW4Model m, RW4Section s, Stream w)
        {
            var p1 = (uint)w.Position + 16;

            w.WriteU32(p1);
            w.WriteU32((uint)items.Length);
            w.WriteU32(0);
            w.WriteU32(0);
            foreach (var i in items)
            {
                i.Write(w);
            }
        }
예제 #24
0
        public UInt32 id;           // hash or guid, referenced by Anim to specify which bones to animate?

        public override void Read(RW4Model m, RW4Section s, Stream r)
        {
            if (s.type_code != type_code)
            {
                throw new ModelFormatException(r, "HI000", s.type_code);
            }
            var p2 = r.ReadU32();
            var p3 = r.ReadU32();
            var p1 = r.ReadU32();
            var c1 = r.ReadU32();

            id = r.ReadU32();
            r.expect(c1, "HI001");
            if (p1 != r.Position)
            {
                throw new ModelFormatException(r, "HI010", p1);
            }
            if (p2 != p1 + 4 * c1)
            {
                throw new ModelFormatException(r, "HI011", p2);
            }
            if (p3 != p1 + 8 * c1)
            {
                throw new ModelFormatException(r, "HI012", p3);
            }
            items = new Item[c1];
            for (int i = 0; i < c1; i++)
            {
                items[i] = new Item {
                    index = i, name_fnv = r.ReadU32()
                }
            }
            ;
            for (int i = 0; i < c1; i++)
            {
                items[i].flags = r.ReadU32();
            }
            for (int i = 0; i < c1; i++)
            {
                var pind = r.ReadS32();
                if (pind == -1)
                {
                    items[i].parent = null;
                }
                else
                {
                    items[i].parent = items[pind];
                }
            }
        }
        public override void Read(RW4Model m, RW4Section s, Stream r)
        {
            var sn1   = r.ReadS32();
            var count = r.ReadU32();        // always exactly 1, so I am guessing
            var sns   = new Int32[count];

            for (int i = 0; i < count; i++)
            {
                sns[i] = r.ReadS32();
            }

            m.Sections[sn1].GetObject(m, r, out mesh);
            mat = new RW4TexMetadata[count];
            //for (int i = 0; i < count; i++)
            //    m.Sections[sns[i]].GetObject(m, r, out mat[i]);
        }
예제 #26
0
        void pack(Stream src, RW4Model model)
        {
            // Read the DDS
            src.expect(0x20534444, "DDS000");  // 'DDS '
            int headerSize = src.ReadS32();
            if (headerSize < 0x7C) throw new ModelFormatException(src, "DDS001", headerSize);
            var flags = src.ReadU32();
            var height = src.ReadS32();
            var width = src.ReadS32();
            var pitchOrLinearSize = src.ReadU32();
            src.expect(0, "DDS002");  // < depth
            var mipmaps = src.ReadS32();

            src.Seek(src.Position + 11 * 4, SeekOrigin.Begin);
            var pfsize = src.ReadS32();
            if (pfsize < 32) throw new ModelFormatException(src, "DDS011", pfsize);
            var pf_flags = src.ReadU32();
            if ((pf_flags & 4) == 0) throw new ModelFormatException(src, "DDS012", pf_flags);
            var fourcc = src.ReadU32();
            if (fourcc != Texture.DXT5)
                throw new NotSupportedException("Texture packing currently only supports DXT5 compressed input textures.");

            src.Seek(headerSize+4, SeekOrigin.Begin);
            var sizes = (from i in Enumerable.Range(0, mipmaps)
                            select Math.Max(width>>i,4)*Math.Max(height>>i,4)  // DXT5: 16 bytes per 4x4=16 pixels
                            ).ToArray();
            var all_mipmaps = new byte[ sizes.Sum() ];
            for (int offset=0, i = 0; i < mipmaps; i++) {
                if (src.Read( all_mipmaps, offset, sizes[i] ) != sizes[i])
                    throw new ModelFormatException(src, "Unexpected EOF reading .DDS file", null);
                offset += sizes[i];
            }

            // Build the RW4
            model.FileType = RW4Model.FileTypes.Texture;
            var texture = new Texture()
            {
                width = (ushort)width,
                height = (ushort)height,
                mipmapInfo = (uint)(0x100 * mipmaps + 0x08),
                textureType = fourcc,
                texData = new TextureBlob { blob = all_mipmaps },
                unk1 = 0
            };
            model.AddObject(texture.texData, TextureBlob.type_code);
            model.AddObject(texture, Texture.type_code);
        }
예제 #27
0
        public override void Read(RW4Model m, RW4Section s, Stream r)
        {
            var p1    = r.ReadU32();
            var count = r.ReadU32();

            r.expect(0, "MS001");      /// These bytes are padding to 16 bytes, but this structure is itself always aligned
            r.expect(0, "MS002");
            if (p1 != r.Position)
            {
                throw new ModelFormatException(r, "MS001", p1);
            }
            items = new T[count];
            for (int i = 0; i < count; i++)
            {
                items[i].Read(r);
            }
        }
예제 #28
0
        public override void Read(RW4Model m, RW4Section s, Stream r)
        {
            int startingPosition = (int)r.Position;

            VertexElements = new List <VertexUsage>();

            r.expect(0x00000000, "Not Zero VF001");
            r.expect(0x00000000, "Not Zero VF002");
            r.expect(0x00000000, "Not Zero VF003");

            _vertexComponents = r.ReadU16(); //amount of 'items' in this vertex?

            VertexSize = r.ReadU16BE();

            _unknown2 = r.ReadU32BE();
            _unknown3 = r.ReadU32BE();

            //uint _unknown4 = r.ReadU32BE(); //zero
            for (int i = 0; i < _vertexComponents; i++)
            {
                byte unk1 = r.ReadU8(); //always zero

                ushort _offset  = r.ReadU16BE();
                ushort _type    = r.ReadU16BE();
                ushort _usage   = r.ReadU16BE();
                byte   _index   = r.ReadU8();
                byte   _unknown = r.ReadU8();
                ushort unk3     = r.ReadU16BE(); //always zero
                byte   unk4     = r.ReadU8();    //always zero

                VertexElements.Add(new VertexUsage()
                {
                    Unknown1        = unk1,
                    Offset          = _offset,
                    Usage           = (D3DDECLUSAGE)_usage,
                    Index           = _index,
                    DeclarationType = (D3DDECLTYPE)_type,
                    Unknown2        = _unknown,
                    Unknown3        = unk3,
                    Unknown4        = unk4
                });
            }

            size = (int)r.Position - startingPosition;
        }
예제 #29
0
        public override void Read(RW4Model m, RW4Section s, Stream r)
        {
            Materials = new List <MaterialTextureReference>();

            long pos = r.Position;

            Size = r.ReadU32();

            Header = r.ReadBytes(28); //read the header
            //find the vertex format
            RW4Section vertexFormatSection = m.Sections.Find(sec => sec.TypeCode == SectionTypeCodes.VertexFormat);

            if (vertexFormatSection != null)
            {
                int vertexFormatSize = vertexFormatSection.obj.ComputeSize();
                VertexFormatData = r.ReadBytes(vertexFormatSize);
            }

            long currentPos = r.Position;
            uint u2D        = 0;

            while (u2D != 0x2D)
            {
                u2D = r.ReadU32();
            }
            int additionalDataSize = (int)r.Position - (int)currentPos - 4;

            r.Seek(currentPos, SeekOrigin.Begin);

            AdditionalData = r.ReadBytes(additionalDataSize);

            for (int i = 0; i < 6; i++)
            {
                MaterialTextureReference mat = new MaterialTextureReference();
                mat.Unknown1          = r.ReadU32();
                mat.Unknown2          = r.ReadU32();
                mat.TextureInstanceId = r.ReadU32();
                mat.Unknown3          = r.ReadU32();
                mat.Unknown4          = r.ReadU32();
                mat.Unknown5          = r.ReadU32();
                Materials.Add(mat);
            }

            Data = r.ReadBytes((int)Size - (int)(r.Position - pos));
        }
예제 #30
0
        /*
         * void unpackModel(RW4Model model, string outputFileName)
         * {
         *  var meshes = model.GetObjects(RW4Mesh.type_code);
         *  if (meshes.Count != 1) throw new NotSupportedException("Only exactly one mesh supported.");
         *  var mesh = meshes[0] as RW4Mesh;
         *
         *  if (mesh.vertices == null) throw new NotSupportedException("Only models with a vertex buffer can be unpacked.");
         *
         *  new OgreXmlWriter(mesh.vertices.vertices.ToArray(),
         *                    mesh.triangles.triangles.ToArray(),
         *                    outputFileName);
         *  type = "mesh";
         * }
         * */

        void unpackTexture(RW4Model model, string outputFileName)
        {
            var textures = model.GetObjects(Texture.type_code);
            //  if (textures.Count != 1)
            //       throw new NotSupportedException("Only exactly one texture supported in a texture rw4.");
            int j = 0;

            foreach (Texture texture in textures)
            {
                using (var stream = File.Create(outputFileName + j.ToString() + ".dds"))
                {
                    stream.WriteU32(0x20534444); // 'DDS '
                    stream.WriteU32(0x7C);       // header size
                    stream.WriteU32(0xA1007);    // flags:
                    stream.WriteU32(texture.height);
                    stream.WriteU32(texture.width);
                    stream.WriteU32((uint)texture.height * (uint)texture.width);  // size of top mipmap level... at least in DXT5 for >4x4
                    stream.WriteU32(0);
                    stream.WriteU32(texture.mipmapInfo / 0x100);
                    for (int i = 0; i < 11; i++)
                    {
                        stream.WriteU32(0);
                    }

                    // pixel format
                    stream.WriteU32(32);
                    stream.WriteU32(4);  // DDPF_FOURCC?
                    stream.WriteU32(texture.textureType);
                    stream.WriteU32(32);
                    stream.WriteU32(0xff0000);
                    stream.WriteU32(0x00ff00);
                    stream.WriteU32(0x0000ff);
                    stream.WriteU32(0xff000000);
                    stream.WriteU32(0);  // 0x41008
                    for (int i = 0; i < 4; i++)
                    {
                        stream.WriteU32(0);
                    }

                    stream.Write(texture.texData.blob, 0, texture.texData.blob.Length);
                    j++;
                }
                type = "texture";
            }
        }