public Block_3301(EndianReader reader, bool loadSkin, Vertex[] Vertices) : base(reader, 0x3301) { FirstNodeID = reader.ReadInt16(); NodeCount = reader.ReadInt16(); if (!loadSkin) reader.Skip(Vertices.Length * 4); else foreach (var v in Vertices) { var val = Vector.FromUByte4(reader.ReadUInt32()); nodes.Add(val); v.Values.Add(new VertexValue(val, VertexValue.ValueType.UInt8_4, "blendindices", 0)); } }
public UVDataBlock_3001(EndianReader reader, bool loadMesh, Vertex[] Vertices) : base(reader, 0x3001) { DataCount = reader.ReadInt32(); //vCount x2E00 = reader.ReadInt16(); //2E00 reader.EndianType = EndianFormat.BigEndian; unkUV0 = reader.ReadInt16(); //flags? 0x1C00 when world unkUV1 = reader.ReadByte(); unkUV2 = reader.ReadByte(); unkUV3 = reader.ReadByte(); unkUV4 = reader.ReadByte(); //0x00 when world, else 0x20 DataSize = reader.ReadByte(); if (!loadMesh) reader.SeekTo(EOBOffset); else for (int i = 0; i < DataCount; i++) { Vector tex0 = new Vector(); #region switch switch (DataSize) { case 8: tex0 = Vector.FromUByteN4(reader.ReadUInt32()); reader.Skip(0); break; case 12: reader.Skip(4); break; case 16: reader.Skip(12); break; case 20: reader.Skip(16); break; case 24: reader.Skip(16); break; case 28: reader.Skip(20); break; case 32: reader.Skip(16); break; case 36: reader.Skip(24); break; case 44: reader.Skip(28); break; } #endregion int u = reader.ReadInt16(); int v = reader.ReadInt16(); //var tex0 = new RealQuat(((float)a + (float)0) / (float)0xFFFF, ((float)b + (float)0) / (float)0xFFFF); var tex1 = new Vector((float)u / (float)(0x7FFF), (float)v / (float)(0x7FFF)); #region switch switch (DataSize) { case 8: reader.Skip(0); break; case 12: reader.Skip(4); break; case 16: reader.Skip(0); break; case 20: reader.Skip(0); break; case 24: reader.Skip(4); break; case 28: reader.Skip(4); break; case 32: reader.Skip(12); break; case 36: reader.Skip(8); break; case 44: reader.Skip(12); break; } #endregion //Vertices[i].Values.Add(new VertexValue(tex0, 0, "normal", 0)); Vertices[i].Values.Add(new VertexValue(tex1, VertexValue.ValueType.Int16_N2, "texcoords", 0)); } reader.EndianType = EndianFormat.LittleEndian; }
public VertexBlock_F100(EndianReader reader, bool loadMesh, int geomUnk01) : base(reader, 0xF100) { DataCount = reader.ReadInt32(); Data = new Vertex[DataCount]; if (DataCount == 0) return; if (geomUnk01 != 134 && geomUnk01 != 142) { CentreX = reader.ReadInt16(); CentreY = reader.ReadInt16(); CentreZ = reader.ReadInt16(); RadiusX = reader.ReadInt16(); RadiusY = reader.ReadInt16(); RadiusZ = reader.ReadInt16(); } if (!loadMesh) reader.SeekTo(EOBOffset); else for (int i = 0; i < DataCount; i++) { Vertex v; if (geomUnk01 == 134 || geomUnk01 == 142) { v = new Vertex() { FormatName = "S3D_World" }; var data = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); v.Values.Add(new VertexValue(data, VertexValue.ValueType.Float32_3, "position", 0)); } else { v = new Vertex() { FormatName = "S3D_Compressed" }; var data = new Vector(reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16()); v.Values.Add(new VertexValue(data, VertexValue.ValueType.Int16_N4, "position", 0)); } Data[i] = v; } }
public Block_1A01(EndianReader reader, bool loadSkin, Vertex[] Vertices) : base(reader, 0x1A01) { if (!loadSkin) reader.Skip(Vertices.Length * 4); else foreach (var v in Vertices) { var val = Vector.FromUByteN4(reader.ReadUInt32()); v.Values.Add(new VertexValue(val, VertexValue.ValueType.UInt8_4, "blendweight", 0)); } }
public override void LoadRaw() { if (RawLoaded) return; var bb = BoundingBoxes[0]; var IH = (Halo1PC.CacheFile.CacheIndexHeader)cache.IndexHeader; var reader = cache.Reader; for (int i = 0; i < ModelSections.Count; i++) { var section = ModelSections[i]; List<int> tIndices = new List<int>(); List<Vertex> tVertices = new List<Vertex>(); for (int j = 0; j < section.Submeshes.Count; j++) { var submesh = (Halo1PC.gbxmodel.ModelSection.Submesh)section.Submeshes[j]; #region Read Indices submesh.FaceIndex = tIndices.Count; var strip = new List<int>(); reader.SeekTo(submesh.FaceOffset + IH.vertDataOffset + IH.indexDataOffset); for (int k = 0; k < submesh.FaceCount; k++) strip.Add(reader.ReadUInt16() + tVertices.Count); strip = ModelFunctions.GetTriangleList(strip.ToArray(), 0, strip.Count, 5); strip.Reverse(); submesh.FaceCount = strip.Count; tIndices.AddRange(strip); #endregion #region Read Vertices reader.SeekTo(submesh.VertOffset + IH.vertDataOffset); for (int k = 0; k < submesh.VertexCount; k++) { var v = new Vertex() { FormatName = "Halo1PC_Skinned" }; var position = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var normal = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var binormal = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var tangent = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var texcoord = new Vector(reader.ReadSingle() * uScale, 1f - reader.ReadSingle() * vScale); var nodes = (Flags.Values[1]) ? new Vector(submesh.LocalNodes[reader.ReadInt16()], submesh.LocalNodes[reader.ReadInt16()], 0, 0) : new Vector(reader.ReadInt16(), reader.ReadInt16(), 0, 0); var weights = new Vector(reader.ReadSingle(), reader.ReadSingle(), 0, 0); v.Values.Add(new VertexValue(position, VertexValue.ValueType.Float32_3, "position", 0)); v.Values.Add(new VertexValue(normal, VertexValue.ValueType.Float32_3, "normal", 0)); v.Values.Add(new VertexValue(binormal, VertexValue.ValueType.Float32_3, "binormal", 0)); v.Values.Add(new VertexValue(tangent, VertexValue.ValueType.Float32_3, "tangent", 0)); v.Values.Add(new VertexValue(texcoord, VertexValue.ValueType.Float32_2, "texcoords", 0)); v.Values.Add(new VertexValue(nodes, VertexValue.ValueType.Int16_N2, "blendindices", 0)); v.Values.Add(new VertexValue(weights, VertexValue.ValueType.Float32_2, "blendweight", 0)); tVertices.Add(v); bb.XBounds = new Range<float>( Math.Min(bb.XBounds.Min, position.X), Math.Max(bb.XBounds.Max, position.X)); bb.YBounds = new Range<float>( Math.Min(bb.YBounds.Min, position.Y), Math.Max(bb.YBounds.Max, position.Y)); bb.ZBounds = new Range<float>( Math.Min(bb.ZBounds.Min, position.Z), Math.Max(bb.ZBounds.Max, position.Z)); } #endregion } section.Indices = tIndices.ToArray(); section.Vertices = tVertices.ToArray(); IndexInfoList.Add(new IndexBufferInfo() { FaceFormat = 3 }); VertInfoList.Add(new VertexBufferInfo() { VertexCount = section.TotalVertexCount }); } RawLoaded = true; }
public override void LoadRaw() { if (RawLoaded) return; var reader = cache.Reader; #region Read Indices int[] indices = new int[indexCount]; reader.SeekTo(indexOffset); for (int i = 0; i < indexCount; i++) indices[i] = reader.ReadUInt16(); #endregion for (int i = 0; i < ModelSections.Count; i++) { var section = ModelSections[i]; var tempVerts = new List<Vertex>(); if (section.Submeshes.Count == 0) continue; #region Read Vertices for (int j = 0; j < section.Submeshes.Count; j++) { var mesh = (Lightmap.Material)section.Submeshes[j]; reader.SeekTo(mesh.vertsOffset); for (int k = 0; k < mesh.VertexCount; k++) { var v = new Vertex() { FormatName = "Halo1PC_World" }; var position = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var normal = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var binormal = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var tangent = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var texcoord = new Vector(reader.ReadSingle(), 1f - reader.ReadSingle()); v.Values.Add(new VertexValue(position, VertexValue.ValueType.Float32_3, "position", 0)); v.Values.Add(new VertexValue(normal, VertexValue.ValueType.Float32_3, "normal", 0)); v.Values.Add(new VertexValue(binormal, VertexValue.ValueType.Float32_3, "binormal", 0)); v.Values.Add(new VertexValue(tangent, VertexValue.ValueType.Float32_3, "tangent", 0)); v.Values.Add(new VertexValue(texcoord, VertexValue.ValueType.Float32_2, "texcoords", 0)); tempVerts.Add(v); } } #endregion #region Copy & Translate Indices int offset = section.Submeshes[0].FaceIndex; section.Indices = new int[section.TotalFaceCount]; Array.Copy(indices, offset, section.Indices, 0, section.TotalFaceCount); section.Vertices = tempVerts.ToArray(); int pos = 0; for (int j = 0; j < section.Submeshes.Count; j++) { var mesh = section.Submeshes[j]; mesh.FaceIndex -= offset; for (int k = 0; k < mesh.FaceCount; k++) section.Indices[k + mesh.FaceIndex] += pos; Array.Reverse(section.Indices, mesh.FaceIndex, mesh.FaceCount); pos += mesh.VertexCount; } #endregion IndexInfoList.Add(new mode.IndexBufferInfo() { FaceFormat = 3 }); VertInfoList.Add(new mode.VertexBufferInfo() { VertexCount = section.TotalVertexCount }); } RawLoaded = true; }
protected void LoadModelExtras() { var mode = this; #region Mesh Merging foreach (var reg in mode.Regions) { foreach (var perm in reg.Permutations) { if (perm.PieceCount < 2) continue; var firstPart = mode.ModelSections[perm.PieceIndex]; if (firstPart.Submeshes.Count == 0) continue; var verts = firstPart.Vertices.ToList(); var indices = firstPart.Indices.ToList(); for (int i = 1; i < perm.PieceCount; i++) { var nextPart = mode.ModelSections[perm.PieceIndex + i]; foreach (var mesh in nextPart.Submeshes) { firstPart.Submeshes.Add(mesh); mesh.FaceIndex += indices.Count; } for (int j = 0; j < nextPart.Indices.Length; j++) nextPart.Indices[j] += verts.Count; verts.AddRange(nextPart.Vertices); indices.AddRange(nextPart.Indices); nextPart.UnloadRaw(); //save memory seeing as it wont be used now } firstPart.Vertices = verts.ToArray(); firstPart.Indices = indices.ToArray(); } } #endregion #region Mesh Splitting if (mode.InstancedGeometryIndex == -1) return; var part = mode.ModelSections[mode.InstancedGeometryIndex]; var list = new List<mode.ModelSection>(); for (int i = 0; i < part.Submeshes.Count; i++) { var submesh = part.Submeshes[i]; for (int j = submesh.SubsetIndex; j < (submesh.SubsetIndex + submesh.SubsetCount); j++) { var set = part.Subsets[j]; var vList = ModelFunctions.GetTriangleList(part.Indices, set.FaceIndex, set.FaceCount, mode.IndexInfoList[part.FacesIndex].FaceFormat); var newStrip = vList.ToArray(); var min = vList.Min(); var max = vList.Max(); //adjust faces to start at 0, seeing as //we're going to use a new set of vertices for (int k = 0; k < newStrip.Length; k++) newStrip[k] -= min; var verts = new Vertex[(max - min) + 1]; for (int k = 0; k < verts.Length; k++) //need to deep clone in case the vertices need to be verts[k] = (Vertex)ModelFunctions.DeepClone(part.Vertices[k + min]); //transformed, so it doesnt transform all instances #region Make new instances var newPart = new mode.ModelSection() { Vertices = verts, Indices = newStrip, Submeshes = new List<mode.ModelSection.Submesh>(), Subsets = new List<mode.ModelSection.Subset>(), VertexFormat = 1, OpaqueNodesPerVertex = part.OpaqueNodesPerVertex, NodeIndex = mode.GeomInstances[j].NodeIndex, VertsIndex = mode.VertInfoList.Count, FacesIndex = mode.IndexInfoList.Count }; mode.VertInfoList.Add(new mode.VertexBufferInfo() { VertexCount = verts.Length //dont need the rest }); mode.IndexInfoList.Add(new mode.IndexBufferInfo() { FaceFormat = 3 //dont need the rest }); var newMesh = new mode.ModelSection.Submesh() { SubsetCount = 1, SubsetIndex = 0, FaceIndex = 0, FaceCount = newStrip.Length, ShaderIndex = submesh.ShaderIndex, VertexCount = verts.Length }; var newSet = new mode.ModelSection.Subset() { SubmeshIndex = 0, FaceIndex = 0, FaceCount = newStrip.Length, VertexCount = verts.Length }; #endregion newPart.Submeshes.Add(newMesh); newPart.Subsets.Add(newSet); list.Add(newPart); } } //clear raw to save memory seeing as it wont be used anymore mode.ModelSections[mode.InstancedGeometryIndex].UnloadRaw(); mode.ModelSections.AddRange(list.ToArray()); var newRegion = new mode.Region() { Name = "Instances", Permutations = new List<mode.Region.Permutation>() }; for (int i = 0; i < list.Count; i++) { var newPerm = new mode.Region.Permutation() { Name = mode.GeomInstances[i].Name, PieceIndex = mode.InstancedGeometryIndex + i + 1, PieceCount = 1 }; newRegion.Permutations.Add(newPerm); } for (int i = 0; i < newRegion.Permutations.Count; i++) { var modelPart = mode.ModelSections[newRegion.Permutations[i].PieceIndex]; var instance = mode.GeomInstances[i]; //negative scale flips the faces after transform, fix it if (instance.TransformScale < 0) Array.Reverse(modelPart.Indices); for (int j = 0; j < modelPart.Vertices.Length; j++) { var vert = modelPart.Vertices[j]; VertexValue p, n, v, w; vert.TryGetValue("position", 0, out p); vert.TryGetValue("normal", 0, out n); p.Data *= instance.TransformScale; p.Data.Point3DTransform(instance.TransformMatrix); n.Data *= instance.TransformScale; n.Data.Vector3DTransform(instance.TransformMatrix); if (vert.TryGetValue("blendindices", 0, out v)) v.Data = new Vector(instance.NodeIndex, 0, 0, 0); else vert.Values.Add(new VertexValue(new Vector(instance.NodeIndex, 0, 0, 0), VertexValue.ValueType.Int8_N4, "blendindices", 0)); if (vert.TryGetValue("blendweight", 0, out w)) w.Data = new Vector(instance.NodeIndex, 0, 0, 0); else vert.Values.Add(new VertexValue(new Vector(1, 0, 0, 0), VertexValue.ValueType.Int8_N4, "blendweight", 0)); } } mode.Regions.Add(newRegion); #endregion }
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, Endian.EndianFormat.LittleEndian); #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; #region Clusters for (int i = 0; i < Clusters.Count; i++) { var section = (Halo2Xbox.scenario_structure_bsp.ModelSection)ModelSections[i]; if (section.rSize.Length == 0 || section.vertcount == 0) { IndexInfoList.Add(new mode.IndexBufferInfo()); continue; } var data = cache.GetRawFromID(section.rawOffset, section.rawSize); var ms = new MemoryStream(data); var reader = new EndianReader(ms, Endian.EndianFormat.LittleEndian); #region Read Submeshes for (int j = 0; j < section.rSize[0] / 72; j++) { var mesh = new mode.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 #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 section.Vertices = new Vertex[section.vertcount]; 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(); var p = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); v.Values.Add(new VertexValue(p, 0, "position", 0)); section.Vertices[j] = v; } #region Read UVs and Normals for (int j = 0; j < section.vertcount; j++) { reader.SeekTo(section.hSize + section.rOffset[uIndex] + (8 * j)); var v = section.Vertices[j]; var uv = new Vector(reader.ReadSingle(), 1 - reader.ReadSingle()); v.Values.Add(new VertexValue(uv, 0, "texcoords", 0)); } for (int j = 0; j < section.vertcount; j++) { reader.SeekTo(section.hSize + section.rOffset[uIndex + 1] + (12 * j)); var v = section.Vertices[j]; var n = Vector.FromHenDN3(reader.ReadUInt32()); v.Values.Add(new VertexValue(n, 0, "normal", 0)); } #endregion reader.SeekTo(40); section.Indices = new int[reader.ReadUInt16()]; reader.SeekTo(section.hSize + section.rOffset[iIndex]); for (int j = 0; j < section.Indices.Length; j++) section.Indices[j] = reader.ReadUInt16(); var facetype = 5; if (section.facecount * 3 == section.Indices.Length) facetype = 3; IndexInfoList.Add(new mode.IndexBufferInfo() { FaceFormat = facetype }); } #endregion #region Instances if (GeomInstances.Count == 0) { RawLoaded = true; return; } for (int i = GeomInstances[0].SectionIndex; i < ModelSections.Count; i++) { var section = (Halo2Xbox.scenario_structure_bsp.ModelSection)ModelSections[i]; var geomIndex = i - Clusters.Count; if (section.rSize.Length == 0 || section.vertcount == 0) { IndexInfoList.Add(new mode.IndexBufferInfo()); continue; } var data = cache.GetRawFromID(section.rawOffset, section.rawSize); var ms = new MemoryStream(data); var reader = new EndianReader(ms, Endian.EndianFormat.LittleEndian); #region Read Submeshes for (int j = 0; j < section.rSize[0] / 72; j++) { var mesh = new mode.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 #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 section.Vertices = new Vertex[section.vertcount]; 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(); var p = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); v.Values.Add(new VertexValue(p, 0, "position", 0)); section.Vertices[j] = v; } #region Read UVs and Normals for (int j = 0; j < section.vertcount; j++) { reader.SeekTo(section.hSize + section.rOffset[uIndex] + (8 * j)); var v = section.Vertices[j]; var uv = new Vector(reader.ReadSingle(), 1 - reader.ReadSingle()); v.Values.Add(new VertexValue(uv, 0, "texcoords", 0)); //DecompressVertex(ref v, BoundingBoxes[geomIndex]); } 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 reader.SeekTo(40); section.Indices = new int[reader.ReadUInt16()]; reader.SeekTo(section.hSize + section.rOffset[iIndex]); for (int j = 0; j < section.Indices.Length; j++) section.Indices[j] = reader.ReadUInt16(); var facetype = 5; if (section.facecount * 3 == section.Indices.Length) facetype = 3; IndexInfoList.Add(new mode.IndexBufferInfo() { FaceFormat = facetype }); } #endregion RawLoaded = true; }