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); } }
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 }
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); }
public override void Write(RW4Model m, RW4Section s, Stream w) { for (int i = 0; i < items.Length; i++) { items[i].Write(w); } }
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); }
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; } }
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 Read(RW4Model m, RW4Section s, Stream r) { if (!Relocatable()) { this.required_position = r.Position; } blob = r.ReadBytes((int)s.Size); }
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); }
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); } }
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); } }
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]); } }
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); }
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); }
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); } }
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); }
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); } }
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]); }
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); } }
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)); }
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; }
public UInt32 mipmapInfo; // 0x708 for 64x64 (7 mipmap levels); 0x808 for 128x128 (8 mipmap levels) public override void Read(RW4Model m, RW4Section s, Stream r) { if (s.type_code != type_code) { throw new ModelFormatException(r, "T000", s.type_code); } textureType = r.ReadU32(); r.expect(8, "T001"); unk1 = r.ReadU32(); width = r.ReadU16(); height = r.ReadU16(); mipmapInfo = r.ReadU32(); r.expect(0, "T002"); r.expect(0, "T003"); var sec = r.ReadS32(); m.Sections[sec].GetObject(m, r, out texData); }
public void RemoveSection(RW4Section section) { if (Header.Sections[(int)section.Number] != section) { throw new ArgumentException("Attempt to remove invalid section."); } //var new_sections = new RW4Section[header.Sections.Length - 1]; /*for (int i = 0; i < section.Number; i++) * new_sections[i] = header.Sections[i]; * for (int i = (int)section.Number; i < new_sections.Length; i++ ) * { * new_sections[i] = header.Sections[i + 1]; * new_sections[i].Number = (uint)i; * }*/ // header.Sections = new_sections; section.Number = 0xffffffff; }
public override void Read(RW4Model m, RW4Section s, Stream r) { if (s.type_code != type_code) { throw new ModelFormatException(r, "SK000", s.type_code); } r.expect(0x400000, "SK001"); unk1 = r.ReadU32(); // r.expect(unk1=0x8d6da0, "SK002"); //< TODO: Not universal, but not sure other decoding is robust with other values var sn1 = r.ReadS32(); var sn2 = r.ReadS32(); var sn3 = r.ReadS32(); m.Sections[sn1].GetObject(m, r, out mat3); m.Sections[sn2].GetObject(m, r, out jointInfo); m.Sections[sn3].GetObject(m, r, out mat4); }
public RW4Section InsertSection(int index) { /* var new_sections = new RW4Section[header.Sections.Count + 1]; * for (int i = 0; i < index; i++) * new_sections[i] = header.Sections[i]; * for (int i = index + 1; i < new_sections.Length; i++) * { * new_sections[i] = header.Sections[i - 1]; * new_sections[i].Number = (uint)i; * }*/ RW4Section newSection = new RW4Section(); newSection.Number = (uint)index; Header.Sections.Add(newSection); return(newSection); }
public override void Read(RW4Model m, RW4Section s, Stream r) { VertexFormat vFormat = null; if (m.Sections.Exists(sc => sc.TypeCode == SectionTypeCodes.VertexFormat)) { vFormat = m.Sections.Single(sc => sc.TypeCode == SectionTypeCodes.VertexFormat).obj as VertexFormat; } 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, vFormat); } } }
public override void Write(RW4Model m, RW4Section s, Stream w) { if (vertices != null) { vert_count = (uint)vertices.vertices.Length; } if (triangles != null) { tri_count = (uint)triangles.triangles.Length; } w.WriteU32(40); w.WriteU32(4); w.WriteU32(triangles.section.Number); w.WriteU32(tri_count); w.WriteU32(1); w.WriteU32(0); w.WriteU32(tri_count * 3); w.WriteU32(0); w.WriteU32(vert_count); w.WriteU32(vertices.section.Number); }
private void SaveRW4Model(DatabaseIndex index, RW4Model model) { //Save the new thing to a stream! ModifiedRW4File modifiedData = new ModifiedRW4File(); foreach (RW4Section section in model.Sections) { if (section.TypeCode == SectionTypeCodes.Texture) { SporeMaster.RenderWare4.Texture tex = section.obj as SporeMaster.RenderWare4.Texture; model.Sections[(int)tex.texData.section.Number].obj = tex.texData; } } RW4Section meshSection = model.Sections.Find(s => s.TypeCode == SectionTypeCodes.Mesh); if (meshSection != null) { SporeMaster.RenderWare4.RW4Mesh mesh = meshSection.obj as SporeMaster.RenderWare4.RW4Mesh; model.Sections[(int)mesh.vertices.section.Number].obj = mesh.vertices; model.Sections[(int)mesh.triangles.section.Number].obj = mesh.triangles; model.Sections[(int)mesh.vertices.vertices.section.Number].obj = mesh.vertices.vertices.section.obj; model.Sections[(int)mesh.triangles.triangles.section.Number].obj = mesh.triangles.triangles.section.obj; } //save back the model using (MemoryStream writer = new MemoryStream()) { model.Write(writer); modifiedData.RW4FileData = writer.ToArray(); index.ModifiedData = modifiedData; index.IsModified = true; index.Compressed = false; } }
public override void Read(RW4Model m, RW4Section s, Stream r) { if (s.type_code != type_code) { throw new ModelFormatException(r, "TM000", s.type_code); } // This section is hard to really decode because it is almost constant across different models! var p = (long)s.Size - (unk_data_2.Length) * 4 - 4; if (p < 0) { throw new ModelFormatException(r, "TM001", p); } unk_data_1 = r.ReadBytes((int)p); var sn = r.ReadS32(); for (int i = 0; i < unk_data_2.Length; i++) { unk_data_2[i] = r.ReadS32(); } m.Sections[sn].GetObject(m, r, out texture); }