private Shape[] ReadShapes(FileReader reader, BufferData buffer) { uint numMeshes = reader.ReadUInt32(); reader.AlignPadding(0x20); Shape[] meshes = new Shape[numMeshes]; for (int mIdx = 0; mIdx < numMeshes; mIdx++) { int boneIndex = reader.ReadInt32(); int vtxDescriptor = reader.ReadInt32(); int numPackets = reader.ReadInt32(); Console.WriteLine($"boneIndex {boneIndex}"); meshes[mIdx] = new Shape(); meshes[mIdx].BoneIndex = boneIndex; ushort[] matrixIndices = new ushort[10]; for (int pIdx = 0; pIdx < numPackets; pIdx++) { ReadPacket(reader, meshes[mIdx], buffer, matrixIndices, vtxDescriptor); } } return(meshes); }
private void ReadPacket(FileReader reader, Shape mesh, BufferData buffer, ushort[] matrixIndices, int vtxDescriptor) { int numMatrices = reader.ReadInt32(); ushort[] indices = reader.ReadUInt16s(numMatrices); for (int i = 0; i < numMatrices; i++) { if (indices[i] == ushort.MaxValue) { continue; } matrixIndices[i] = indices[i]; Console.WriteLine($"matrixIndices {matrixIndices[i]}"); } var NBT = (vtxDescriptor >> 4); bool hasNBT = NBT > 0; uint numDisplayLists = reader.ReadUInt32(); for (int dlIdx = 0; dlIdx < numDisplayLists; dlIdx++) { byte[] flags = reader.ReadBytes(4); int unk1 = reader.ReadInt32(); int dataSize = reader.ReadInt32(); reader.AlignPadding(0x20); long displayListStart = reader.Position; var dlData = new SubStream(reader.BaseStream, displayListStart, dataSize); reader.SeekBegin(displayListStart + dataSize); List <GXVertexLayout> layouts = new List <GXVertexLayout>(); if ((vtxDescriptor & 1) == 1) { layouts.Add(new GXVertexLayout(GXAttributes.PosNormMatrix, GXComponentType.U8, GXAttributeType.INDEX8, 0)); } if ((vtxDescriptor & 2) == 2) { layouts.Add(new GXVertexLayout(GXAttributes.Tex0Matrix, GXComponentType.S8, GXAttributeType.INDEX8, 0)); } layouts.Add(new GXVertexLayout(GXAttributes.Position, GXComponentType.F32, GXAttributeType.INDEX16, buffer.PositionsOffset)); if (hasNBT && false) { layouts.Add(new GXVertexLayout(GXAttributes.NormalBinormalTangent, GXComponentType.F32, GXAttributeType.INDEX16, buffer.NBTOffset)); } else if (buffer.NormalsOffset != 0) { layouts.Add(new GXVertexLayout(GXAttributes.Normal, GXComponentType.F32, GXAttributeType.INDEX16, buffer.NormalsOffset)); } if ((vtxDescriptor & 4) == 4) { layouts.Add(new GXVertexLayout(GXAttributes.Color0, GXComponentType.RGBA8, GXAttributeType.INDEX16, buffer.ColorsOffset)); } int txCoordDescriptor = vtxDescriptor >> 3; for (int tcoordIdx = 0; tcoordIdx < 8; tcoordIdx++) { if ((txCoordDescriptor & 1) == 0x1) { // Only read for the first texcoord layouts.Add(new GXVertexLayout((GXAttributes)(1 << 13 + tcoordIdx), GXComponentType.F32, GXAttributeType.INDEX16, buffer.TexCoordsOffset[tcoordIdx])); txCoordDescriptor >>= 1; } } for (int l = 0; l < layouts.Count; l++) { Console.WriteLine($"layouts {layouts[l].Attribute} {layouts[l].AttType}"); } List <STVertex> vertices = DisplayListHelper.ReadDisplayLists(dlData, reader.BaseStream, layouts.ToArray(), null, matrixIndices); List <STVertex> dupeVertices = new List <STVertex>(); for (int v = 0; v < vertices.Count; v++) { if (vertices[v].BoneIndices.Count > 0 && !dupeVertices.Contains(vertices[v])) { dupeVertices.Add(vertices[v]); var boneIndex = vertices[v].BoneIndices[0]; if (boneIndex >= RigidSkinningIndices.Length) { boneIndex = SmoothSkinningIndices[boneIndex - RigidSkinningIndices.Length]; vertices[v].BoneIndices.Clear(); vertices[v].BoneWeights.Clear(); var envelop = Envelopes[boneIndex]; for (int j = 0; j < envelop.Indices.Length; j++) { vertices[v].BoneIndices.Add(envelop.Indices[j]); vertices[v].BoneWeights.Add(envelop.Weights[j]); Console.WriteLine($"env {envelop.Indices[j]} w {envelop.Weights[j]}"); } } } } mesh.Vertices.AddRange(vertices); } }
private uint GetVertexOffset(FileReader reader) { reader.ReadUInt32(); //count reader.AlignPadding(0x20); return((uint)reader.Position); }