public void LoadMdlBatch(EndianBinaryReader reader, List <ShapePacket> packets, List <Matrix4> gMatTable, List <Vector3> verts) { uint attributeField = reader.ReadUInt32(); ushort packetCount = reader.ReadUInt16(); ushort firstPacketIndex = reader.ReadUInt16(); long nextPos = reader.BaseStream.Position; int mask = 1; for (int i = 0; i < 24; i++) { int attrib = (int)(attributeField & mask) >> i; if (attrib == 1) { ActiveAttributes.Add((GXAttribute)i); } mask = mask << 1; } for (int i = 0; i < packetCount; i++) { reader.BaseStream.Seek(packets[i + firstPacketIndex].dataOffset, System.IO.SeekOrigin.Begin); List <GXVertex> CurrentPrims = ReadMdlPrimitives(reader, packets[i + firstPacketIndex]); var p = packets[i + firstPacketIndex]; Matrix4[] localMats = new Matrix4[p.numMatIndicies]; for (int j = 0; j < p.numMatIndicies; j++) { if (p.matIndicies[j] == 0xFFFF) { continue; } localMats[j] = gMatTable[p.matIndicies[j]]; } List <int> done = new List <int>(); foreach (var v in CurrentPrims) { if (done.Contains(v.Indices[ActiveAttributes.IndexOf(GXAttribute.Position)])) { continue; } if (ActiveAttributes.Contains(GXAttribute.PositionMatrixIndex) && v.Indices[ActiveAttributes.IndexOf(GXAttribute.PositionMatrixIndex)] != 0xFF) { Matrix4 mat = localMats[v.Indices[ActiveAttributes.IndexOf(GXAttribute.PositionMatrixIndex)]]; Matrix4 pos = new Matrix4( new Vector4(verts[v.Indices[ActiveAttributes.IndexOf(GXAttribute.Position)]].X, 0, 0, 0), new Vector4(verts[v.Indices[ActiveAttributes.IndexOf(GXAttribute.Position)]].Y, 0, 0, 0), new Vector4(verts[v.Indices[ActiveAttributes.IndexOf(GXAttribute.Position)]].Z, 0, 0, 0), new Vector4(1, 0, 0, 0) ); Matrix4 newV = Matrix4.Mult(mat, pos); verts[v.Indices[ActiveAttributes.IndexOf(GXAttribute.Position)]] = new Vector3(newV.M11, newV.M21, newV.M31); //verts[v.Indices[ActiveAttributes.IndexOf(GXAttribute.Position)]] = Vector3.TransformVector(verts[v.Indices[ActiveAttributes.IndexOf(GXAttribute.Position)]], mat); done.Add(v.Indices[ActiveAttributes.IndexOf(GXAttribute.Position)]); } } RawVertices.AddRange(CurrentPrims); } reader.BaseStream.Seek(nextPos, System.IO.SeekOrigin.Begin); //UploadBufferData(); }
/// <summary></summary> /// <param name="c"></param> /// <param name="section_info">Can be null if tag data doesn't have it</param> /// <param name="gbi"></param> /// <returns></returns> internal bool Reconstruct(Blam.CacheFile c, global_geometry_section_info_struct section_info, geometry_block_info_struct gbi) { int index = 0; int x; byte[][] data = gbi.GeometryBlock; if (data == null) { return(false); } foreach (geometry_block_resource_block gb in gbi.Resources) { using (IO.EndianReader er = new BlamLib.IO.EndianReader(data[index])) { switch (gb.Type.Value) { #region TagBlock case (int)geometry_block_resource_type.TagBlock: int count = gb.GetCount(); switch (gb.PrimaryLocater.Value) { case OffsetParts: Parts.Resize(count); Parts.Read(er); break; case OffsetSubparts: Subparts.Resize(count); Subparts.Read(er); break; case OffsetVisibilityBounds: VisibilityBounds.Resize(count); VisibilityBounds.Read(er); break; case OffsetStripIndices: StripIndices.Resize(count); StripIndices.Read(er); break; case OffsetMoppReorderTable: MoppReorderTable.Resize(count); MoppReorderTable.Read(er); break; case OffsetVertexBuffers: VertexBuffers.Resize(count); VertexBuffers.Read(er); break; } break; #endregion #region TagData case (int)geometry_block_resource_type.TagData: switch (gb.PrimaryLocater.Value) { case OffsetVisibilityMoppCode: VisibilityMoppCode.Reset(er.ReadBytes(gb.Size)); break; } break; #endregion #region VertexBuffer case (int)geometry_block_resource_type.VertexBuffer: var vb_defs = (c.TagIndexManager as InternalCacheTagIndex).kVertexBuffers; var stream_readers = new Render.VertexBufferInterface.StreamReader[VertexBuffers.Count]; for (x = 0; x < VertexBuffers.Count; x++) { VertexBuffers[x].VertexBuffer.InitializeStreamReader(vb_defs, out stream_readers[x]); } if (RawVertices.Count == 0) { int vertex_count = section_info != null ? section_info.TotalVertexCount : gb.Size.Value / VertexBuffers[0].VertexBuffer.StrideSize; RawVertices.Resize(vertex_count); } for (x = 0; x < RawVertices.Count; x++) { RawVertices[x].Reconstruct(section_info, gb, er, stream_readers); } break; #endregion } } index++; } VertexBuffers.DeleteAll(); return(true); }
public virtual void ReadChildData(BinaryReader reader) { int x = 0; for (x = 0; (x < _shaders.Count); x = (x + 1)) { Shaders.Add(new DecoratorShaderReferenceBlockBlock()); Shaders[x].Read(reader); } for (x = 0; (x < _shaders.Count); x = (x + 1)) { Shaders[x].ReadChildData(reader); } for (x = 0; (x < _classes.Count); x = (x + 1)) { Classes.Add(new DecoratorClassesBlockBlock()); Classes[x].Read(reader); } for (x = 0; (x < _classes.Count); x = (x + 1)) { Classes[x].ReadChildData(reader); } for (x = 0; (x < _models.Count); x = (x + 1)) { Models.Add(new DecoratorModelsBlockBlock()); Models[x].Read(reader); } for (x = 0; (x < _models.Count); x = (x + 1)) { Models[x].ReadChildData(reader); } for (x = 0; (x < _rawVertices.Count); x = (x + 1)) { RawVertices.Add(new DecoratorModelVerticesBlockBlock()); RawVertices[x].Read(reader); } for (x = 0; (x < _rawVertices.Count); x = (x + 1)) { RawVertices[x].ReadChildData(reader); } for (x = 0; (x < _indices.Count); x = (x + 1)) { Indices.Add(new DecoratorModelIndicesBlockBlock()); Indices[x].Read(reader); } for (x = 0; (x < _indices.Count); x = (x + 1)) { Indices[x].ReadChildData(reader); } for (x = 0; (x < _cachedData.Count); x = (x + 1)) { CachedData.Add(new CachedDataBlockBlock()); CachedData[x].Read(reader); } for (x = 0; (x < _cachedData.Count); x = (x + 1)) { CachedData[x].ReadChildData(reader); } _resourceData.ReadBinary(reader); for (x = 0; (x < _resources.Count); x = (x + 1)) { Resources.Add(new GlobalGeometryBlockResourceBlockBlock()); Resources[x].Read(reader); } for (x = 0; (x < _resources.Count); x = (x + 1)) { Resources[x].ReadChildData(reader); } }