public override void LoadRaw() { if (RawLoaded) return; var data = cache.GetRawFromID(geomRawID); var ms = new MemoryStream(data); var reader = new EndianReader(ms, EndianFormat.BigEndian); var validParts = new Dictionary<int, mode.ModelSection>(); LoadFixups(); #region Read Vertices for (int i = 0; i < ModelSections.Count; i++) { var section = ModelSections[i]; if (section.Submeshes.Count == 0) continue; if (section.VertsIndex >= 0 && section.VertsIndex < VertInfoList.Count) reader.SeekTo(VertInfoList[section.VertsIndex].Offset); if (cache.vertexNode == null) throw new NotSupportedException("No vertex definitions found for " + cache.Version.ToString()); #region Get Vertex Definition XmlNode formatNode = null; foreach (XmlNode node in cache.vertexNode.ChildNodes) { if (Convert.ToInt32(node.Attributes["type"].Value, 16) == section.VertexFormat) { formatNode = node; break; } } if (formatNode == null) throw new NotSupportedException("Format " + section.VertexFormat.ToString() + " not found in definition for " + cache.Version.ToString()); #endregion mode.ModelSection validPart; if (validParts.TryGetValue(section.VertsIndex, out validPart)) { section.Vertices = validPart.Vertices; continue; } else validParts.Add(section.VertsIndex, section); section.Vertices = new Vertex[VertInfoList[section.VertsIndex].VertexCount]; #region Get Vertices for (int j = 0; j < VertInfoList[section.VertsIndex].VertexCount; j++) { mode.BoundingBox bb; section.Vertices[j] = new Vertex(reader, formatNode); if (i >= BoundingBoxes.Count) { bb = new mode.BoundingBox(); bb.XBounds = bb.YBounds = bb.ZBounds = bb.UBounds = bb.VBounds = new RealBounds(0, 0); } else bb = BoundingBoxes[i]; ModelFunctions.DecompressVertex(ref section.Vertices[j], bb); } #endregion } #endregion validParts.Clear(); #region Read Indices for (int i = 0; i < ModelSections.Count; i++) { var section = ModelSections[i]; if (section.Submeshes.Count == 0) continue; if (section.FacesIndex >= 0 && section.FacesIndex < IndexInfoList.Count) reader.SeekTo(IndexInfoList[section.FacesIndex].Offset); mode.ModelSection validPart; if (validParts.TryGetValue(section.FacesIndex, out validPart)) { section.Indices = validPart.Indices; continue; } else validParts.Add(section.FacesIndex, section); section.Indices = new int[section.TotalFaceCount]; for (int j = 0; j < section.TotalFaceCount; j++) section.Indices[j] = (VertInfoList[section.VertsIndex].VertexCount > 0xFFFF) ? reader.ReadInt32() : reader.ReadUInt16(); } #endregion RawLoaded = true; }
public override void LoadRaw() { if (RawLoaded) { return; } for (int i = 0; i < ModelSections.Count; i++) { var section = (Halo2Xbox.render_model.ModelSection)ModelSections[i]; var data = cache.GetRawFromID(section.rawOffset, section.rawSize); var ms = new MemoryStream(data); var reader = new EndianReader(ms, IO.EndianFormat.Little); #region Read Submeshes for (int j = 0; j < section.rSize[0] / 72; j++) { var mesh = new ModelSection.Submesh(); reader.SeekTo(section.hSize + section.rOffset[0] + j * 72 + 4); mesh.ShaderIndex = reader.ReadUInt16(); mesh.FaceIndex = reader.ReadUInt16(); mesh.FaceCount = reader.ReadUInt16(); section.Submeshes.Add(mesh); } #endregion reader.SeekTo(40); section.Indices = new int[reader.ReadUInt16()]; section.Vertices = new Vertex[section.vertcount]; var facetype = 5; if (section.facecount * 3 == section.Indices.Length) { facetype = 3; } IndexInfoList.Add(new IndexBufferInfo() { FaceFormat = facetype }); VertInfoList.Add(new VertexBufferInfo() { VertexCount = section.vertcount }); #region Get Resource Indices int iIndex = 0, vIndex = 0, uIndex = 0, nIndex = 0, bIndex = 0; for (int j = 0; j < section.rType.Length; j++) { switch (section.rType[j] & 0x0000FFFF) { case 32: iIndex = j; break; case 56: switch ((section.rType[j] & 0xFFFF0000) >> 16) { case 0: vIndex = j; break; case 1: uIndex = j; break; case 2: nIndex = j; break; } break; case 100: bIndex = j; break; } } #endregion reader.SeekTo(108); int bCount = reader.ReadUInt16(); int[] bArr = new int[bCount]; if (bCount > 0) { reader.SeekTo(section.hSize + section.rOffset[bIndex]); for (int j = 0; j < bCount; j++) { bArr[j] = reader.ReadByte(); } } #region Read Vertices for (int j = 0; j < section.vertcount; j++) { reader.SeekTo(section.hSize + section.rOffset[vIndex] + ((section.rSize[vIndex] / section.vertcount) * j)); var v = new Vertex() { FormatName = "" }; var p = new Vector( ((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF, ((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF, ((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF, 0); v.Values.Add(new VertexValue(p, 0, "position", 0)); var b = new Vector(); var w = new Vector(); switch (section.type) { case 1: switch (section.bones) { case 0: section.NodeIndex = 0; break; case 1: section.NodeIndex = (bCount > 0) ? bArr[0] : 0; break; } section.Vertices[j] = v; continue; case 2: switch (section.bones) { case 1: b = new Vector(reader.ReadByte(), reader.ReadByte(), 0, 0); w = new Vector(1, 0, 0, 0); break; } break; case 3: switch (section.bones) { case 2: reader.ReadInt16(); b = new Vector(reader.ReadByte(), reader.ReadByte(), 0, 0); w = new Vector((float)reader.ReadByte() / 255f, (float)reader.ReadByte() / 255f, 0, 0); break; case 3: b = new Vector(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), 0); w = new Vector((float)reader.ReadByte() / 255f, (float)reader.ReadByte() / 255f, (float)reader.ReadByte() / 255f, 0); break; case 4: reader.ReadInt16(); b = new Vector(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte()); w = new Vector((float)reader.ReadByte() / 255f, (float)reader.ReadByte() / 255f, (float)reader.ReadByte() / 255f, (float)reader.ReadByte() / 255f); break; } break; } if (bCount > 0) { b.A = (w.A == 0) ? 0 : bArr[(int)b.A]; b.B = (w.B == 0) ? 0 : bArr[(int)b.B]; b.C = (w.C == 0) ? 0 : bArr[(int)b.C]; b.D = (w.D == 0) ? 0 : bArr[(int)b.D]; } v.Values.Add(new VertexValue(b, 0, "blendindices", 0)); v.Values.Add(new VertexValue(w, 0, "blendweight", 0)); section.Vertices[j] = v; } #endregion #region Read UVs and Normals for (int j = 0; j < section.vertcount; j++) { reader.SeekTo(section.hSize + section.rOffset[uIndex] + (4 * j)); var v = section.Vertices[j]; var uv = new Vector(((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF, ((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF); v.Values.Add(new VertexValue(uv, 0, "texcoords", 0)); } for (int j = 0; j < section.vertcount; j++) { reader.SeekTo(section.hSize + section.rOffset[nIndex] + (12 * j)); var v = section.Vertices[j]; var n = Vector.FromHenDN3(reader.ReadUInt32()); v.Values.Add(new VertexValue(n, 0, "normal", 0)); } #endregion ModelFunctions.DecompressVertex(ref section.Vertices, BoundingBoxes[0]); reader.SeekTo(section.hSize + section.rOffset[iIndex]); for (int j = 0; j < section.Indices.Length; j++) { section.Indices[j] = reader.ReadUInt16(); } } RawLoaded = true; }
public override void LoadRaw() { if (RawLoaded) { return; } var mode = this; var data = cache.GetRawFromID(mode.RawID); var ms = new MemoryStream(data); var reader = new EndianReader(ms, IO.EndianFormat.Big); var validParts = new Dictionary <int, mode.ModelSection>(); LoadFixups(); if (mode.IndexInfoList.Count == 0) { throw new Exception("Geometry contains no faces"); } #region Read Vertices for (int i = 0; i < mode.ModelSections.Count; i++) { var section = mode.ModelSections[i]; if (section.Submeshes.Count == 0) { continue; } if (section.VertsIndex >= 0 && section.VertsIndex < mode.VertInfoList.Count) { reader.SeekTo(mode.VertInfoList[section.VertsIndex].Offset); } if (cache.vertexNode == null) { throw new NotSupportedException("No vertex definitions found for " + cache.Version.ToString()); } #region Get Vertex Definition XmlNode formatNode = null; foreach (XmlNode node in cache.vertexNode.ChildNodes) { if (Convert.ToInt32(node.Attributes["type"].Value, 16) == section.VertexFormat) { formatNode = node; break; } } if (formatNode == null) { throw new NotSupportedException("Format " + section.VertexFormat.ToString() + " not found in definition for " + cache.Version.ToString()); } #endregion mode.ModelSection validPart; if (validParts.TryGetValue(section.VertsIndex, out validPart)) { section.Vertices = validPart.Vertices; continue; } else { validParts.Add(section.VertsIndex, section); } section.Vertices = new Vertex[mode.VertInfoList[section.VertsIndex].VertexCount]; #region Get Vertices for (int j = 0; j < mode.VertInfoList[section.VertsIndex].VertexCount; j++) { section.Vertices[j] = new Vertex(reader, formatNode); ModelFunctions.DecompressVertex(ref section.Vertices[j], mode.BoundingBoxes[0]); #region fixups var vert = section.Vertices[j]; VertexValue v; #region rigid fix if (section.NodeIndex != 255 && !mode.Flags.Values[18]) { vert.Values.Add(new VertexValue(new Vector(section.NodeIndex, 0, 0, 0), VertexValue.ValueType.Int8_N4, "blendindices", 0)); vert.Values.Add(new VertexValue(new Vector(1, 0, 0, 0), VertexValue.ValueType.Int8_N4, "blendweight", 0)); } #endregion #region flag 18 fix if (mode.Flags.Values[18]) { VertexValue w; var hasWeights = vert.TryGetValue("blendweight", 0, out w); if (!hasWeights) { w = new VertexValue(new Vector(1, 0, 0, 0), VertexValue.ValueType.Int8_N4, "blendweight", 0); } if (vert.TryGetValue("blendindices", 0, out v)) { v.Data.A = w.Data.A == 0 ? 0 : mode.NodeIndexGroups[i].NodeIndices[(int)v.Data.A].Index; v.Data.B = w.Data.B == 0 ? 0 : mode.NodeIndexGroups[i].NodeIndices[(int)v.Data.B].Index; v.Data.C = w.Data.C == 0 ? 0 : mode.NodeIndexGroups[i].NodeIndices[(int)v.Data.C].Index; v.Data.D = w.Data.D == 0 ? 0 : mode.NodeIndexGroups[i].NodeIndices[(int)v.Data.D].Index; } else { v = new VertexValue(new Vector(0, 0, 0, 0), VertexValue.ValueType.Int8_N4, "blendindices", 0); v.Data.A = mode.NodeIndexGroups[i].NodeIndices[0].Index; vert.Values.Add(v); vert.Values.Add(w); } } #endregion #region rigid_boned fix if (!vert.TryGetValue("blendweight", 0, out v) && vert.TryGetValue("blendindices", 0, out v)) { var q = new Vector( v.Data.A == 0 ? 0 : 1, v.Data.B == 0 ? 0 : 1, v.Data.C == 0 ? 0 : 1, v.Data.D == 0 ? 0 : 1); vert.Values.Add(new VertexValue(q, VertexValue.ValueType.Int8_N4, "blendweight", 0)); } #endregion #endregion } #endregion } #endregion validParts.Clear(); #region Read Indices for (int i = 0; i < mode.ModelSections.Count; i++) { var section = mode.ModelSections[i]; if (section.Submeshes.Count == 0) { continue; } if (section.FacesIndex >= 0 && section.FacesIndex < mode.IndexInfoList.Count) { reader.SeekTo(mode.IndexInfoList[section.FacesIndex].Offset); } mode.ModelSection validPart; if (validParts.TryGetValue(section.FacesIndex, out validPart)) { section.Indices = validPart.Indices; continue; } else { validParts.Add(section.FacesIndex, section); } section.Indices = new int[section.TotalFaceCount]; for (int j = 0; j < section.TotalFaceCount; j++) { section.Indices[j] = (mode.VertInfoList[section.VertsIndex].VertexCount > 0xFFFF) ? reader.ReadInt32() : reader.ReadUInt16(); } } #endregion LoadModelExtras(); mode.RawLoaded = true; }