public SDATInfo(NitroFile sdat, uint offset) { m_Offset = offset; m_Type = sdat.ReadString(m_Offset + 0x00, 4).ToCharArray(); m_Size = sdat.Read32(m_Offset + 0x04); m_RecordOffset = new uint[8]; for (int i = 0; i < 8; i++) { m_RecordOffset[i] = sdat.Read32(m_Offset + 0x08 + (uint)(i * 4)); } m_Reserved = sdat.ReadBlock(m_Offset + 0x28, 24); m_Records = new SDATInfoRecord[8]; for (int i = 0; i < 8; i++) { m_Records[i] = new SDATInfoRecord(sdat, m_Offset + m_RecordOffset[i]); } m_Records0SEQ = new SDATInfoSEQ[m_Records[0].m_Count]; for (int i = 0; i < m_Records[0].m_Count; i++) { m_Records0SEQ[i] = new SDATInfoSEQ(sdat, m_Offset + m_Records[0].m_EntryOffset[i]); } m_Records1SEQARC = new SDATInfoSEQARC[m_Records[1].m_Count]; for (int i = 0; i < m_Records[1].m_Count; i++) { m_Records1SEQARC[i] = new SDATInfoSEQARC(sdat, m_Offset + m_Records[1].m_EntryOffset[i]); } m_Records2BANK = new SDATInfoBANK[m_Records[2].m_Count]; for (int i = 0; i < m_Records[2].m_Count; i++) { m_Records2BANK[i] = new SDATInfoBANK(sdat, m_Offset + m_Records[2].m_EntryOffset[i]); } m_Records3WAVEARC = new SDATInfoWAVEARC[m_Records[3].m_Count]; for (int i = 0; i < m_Records[3].m_Count; i++) { m_Records3WAVEARC[i] = new SDATInfoWAVEARC(sdat, m_Offset + m_Records[3].m_EntryOffset[i]); } m_Records4PLAYER = new SDATInfoPLAYER[m_Records[4].m_Count]; for (int i = 0; i < m_Records[4].m_Count; i++) { m_Records4PLAYER[i] = new SDATInfoPLAYER(sdat, m_Offset + m_Records[4].m_EntryOffset[i]); } m_Records5GROUP = new SDATInfoGROUP[m_Records[5].m_Count]; for (int i = 0; i < m_Records[5].m_Count; i++) { m_Records5GROUP[i] = new SDATInfoGROUP(sdat, m_Offset + m_Records[5].m_EntryOffset[i]); } m_Records6PLAYER2 = new SDATInfoPLAYER2[m_Records[6].m_Count]; for (int i = 0; i < m_Records[6].m_Count; i++) { m_Records6PLAYER2[i] = new SDATInfoPLAYER2(sdat, m_Offset + m_Records[6].m_EntryOffset[i]); } m_Records7STREAM = new SDATInfoSTREAM[m_Records[7].m_Count]; for (int i = 0; i < m_Records[7].m_Count; i++) { m_Records7STREAM[i] = new SDATInfoSTREAM(sdat, m_Offset + m_Records[7].m_EntryOffset[i]); } }
public BMD(NitroFile file) { m_File = file; m_FileName = file.m_Name; /* if (m_File.m_ID == 741) * lolol = true; * else*/ lolol = false; // Keep a list of pointers so it's easier to add/remove entries, space etc. m_PointerList = new List <PointerReference>(); m_ScaleFactor = (float)(1 << (int)m_File.Read32(0x0)); // ModelChunk refers to Bone m_NumModelChunks = m_File.Read32(0x04); m_ModelChunksOffset = m_File.Read32(0x08); AddPointer(0x08); for (int i = 0; i < m_NumModelChunks; i++) { AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x04)); AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x34)); AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x38)); } // PolyChunk refers to Display List m_NumPolyChunks = m_File.Read32(0x0C); m_PolyChunksOffset = m_File.Read32(0x10); AddPointer(0x10); for (int i = 0; i < m_NumPolyChunks; i++) { // Offset to Display List within Display List entries AddPointer((uint)(m_PolyChunksOffset + (i * 8) + 4)); // Offsets within the Display List 16 byte headers AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x04); AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x0C); } m_NumTexChunks = m_File.Read32(0x14); m_TexChunksOffset = m_File.Read32(0x18); m_TextureIDs = new Dictionary <string, uint>(); AddPointer(0x18); for (int i = 0; i < m_NumTexChunks; i++) { AddPointer((uint)(m_TexChunksOffset + (i * 20) + 0)); AddPointer((uint)(m_TexChunksOffset + (i * 20) + 4)); m_TextureIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_TexChunksOffset + (20 * i))), 0), (uint)i); } m_NumPalChunks = m_File.Read32(0x1C); m_PalChunksOffset = m_File.Read32(0x20); m_PaletteIDs = new Dictionary <string, uint>(); AddPointer(0x20); for (int i = 0; i < m_NumPalChunks; i++) { AddPointer((uint)(m_PalChunksOffset + (i * 16) + 0)); AddPointer((uint)(m_PalChunksOffset + (i * 16) + 4)); m_PaletteIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_PalChunksOffset + (16 * i))), 0), (uint)i); } m_NumMatChunks = m_File.Read32(0x24); m_MatChunksOffset = m_File.Read32(0x28); AddPointer(0x28); for (int i = 0; i < m_NumMatChunks; i++) { AddPointer((uint)(m_MatChunksOffset + (i * 48) + 0)); } m_BoneMapOffset = m_File.Read32(0x2C); AddPointer(0x2C); m_Textures = new Dictionary <string, NitroTexture>(); m_ModelChunks = new ModelChunk[m_NumModelChunks]; for (uint c = 0; c < m_NumModelChunks; c++) { ModelChunk mdchunk = new ModelChunk(this); m_ModelChunks[c] = mdchunk; uint mdchunkoffset = m_ModelChunksOffset + (c * 64); mdchunk.m_ID = m_File.Read32(mdchunkoffset); mdchunk.m_Name = m_File.ReadString(m_File.Read32(mdchunkoffset + 0x04), 0); // transforms part { int xscale = (int)m_File.Read32(mdchunkoffset + 0x10); int yscale = (int)m_File.Read32(mdchunkoffset + 0x14); int zscale = (int)m_File.Read32(mdchunkoffset + 0x18); short xrot = (short)m_File.Read16(mdchunkoffset + 0x1C); short yrot = (short)m_File.Read16(mdchunkoffset + 0x1E); short zrot = (short)m_File.Read16(mdchunkoffset + 0x20); int xtrans = (int)m_File.Read32(mdchunkoffset + 0x24); int ytrans = (int)m_File.Read32(mdchunkoffset + 0x28); int ztrans = (int)m_File.Read32(mdchunkoffset + 0x2C); mdchunk.m_Scale = new Vector3((float)xscale / 4096.0f, (float)yscale / 4096.0f, (float)zscale / 4096.0f); mdchunk.m_Rotation = new Vector3(((float)xrot * (float)Math.PI) / 2048.0f, ((float)yrot * (float)Math.PI) / 2048.0f, ((float)zrot * (float)Math.PI) / 2048.0f); mdchunk.m_Translation = new Vector3((float)xtrans / 4096.0f, (float)ytrans / 4096.0f, (float)ztrans / 4096.0f); mdchunk.m_Transform = Helper.SRTToMatrix(mdchunk.m_Scale, mdchunk.m_Rotation, mdchunk.m_Translation); // Used when exporting bones mdchunk.m_20_12Scale = new uint[] { (uint)xscale, (uint)yscale, (uint)zscale }; mdchunk.m_4_12Rotation = new ushort[] { (ushort)xrot, (ushort)yrot, (ushort)zrot }; mdchunk.m_20_12Translation = new uint[] { (uint)xtrans, (uint)ytrans, (uint)ztrans }; // if the chunk has a parent, apply the parent's transform to the chunk's transform. // we don't need to go further than one level because the paren't transform already // went through its parents' transforms. short parent_offset = (short)m_File.Read16(mdchunkoffset + 0x8); if (parent_offset < 0) { int parentchunkid = (int)(c + parent_offset); Matrix4.Mult(ref mdchunk.m_Transform, ref m_ModelChunks[parentchunkid].m_Transform, out mdchunk.m_Transform); } mdchunk.m_ParentOffset = parent_offset; } // If 0x0A is set to 1 the bone has children, if 0 it doesn't mdchunk.m_HasChildren = (m_File.Read16(mdchunkoffset + 0x0A) == 1); mdchunk.m_SiblingOffset = (short)(m_File.Read16(mdchunkoffset + 0x0C)); uint flags = m_File.Read32(mdchunkoffset + 0x3C); mdchunk.m_Billboard = ((flags & 0x1) == 0x1); uint numpairs = m_File.Read32(mdchunkoffset + 0x30); uint matlist = m_File.Read32(mdchunkoffset + 0x34); uint polylist = m_File.Read32(mdchunkoffset + 0x38); mdchunk.m_MatGroups = new MaterialGroup[numpairs]; for (uint i = 0; i < numpairs; i++) { MaterialGroup matgroup = new MaterialGroup(); mdchunk.m_MatGroups[i] = matgroup; byte matID = m_File.Read8(matlist + i); byte polyID = m_File.Read8(polylist + i); uint mchunkoffset = (uint)(m_MatChunksOffset + (matID * 48)); matgroup.m_ID = matID; matgroup.m_Name = m_File.ReadString(m_File.Read32(mchunkoffset), 0); uint texid = m_File.Read32(mchunkoffset + 0x04); uint palid = m_File.Read32(mchunkoffset + 0x08); matgroup.m_TexParams = m_File.Read32(mchunkoffset + 0x20); matgroup.m_PolyAttribs = m_File.Read32(mchunkoffset + 0x24); matgroup.m_DifAmbColors = m_File.Read32(mchunkoffset + 0x28); matgroup.m_SpeEmiColors = m_File.Read32(mchunkoffset + 0x2C); if ((matgroup.m_PolyAttribs & 0x30) == 0x10) { matgroup.m_TexEnvMode = TextureEnvMode.Decal; } else { matgroup.m_TexEnvMode = TextureEnvMode.Modulate; } switch (matgroup.m_PolyAttribs & 0xC0) { case 0x00: matgroup.m_CullMode = CullFaceMode.FrontAndBack; break; case 0x40: matgroup.m_CullMode = CullFaceMode.Front; break; case 0x80: matgroup.m_CullMode = CullFaceMode.Back; break; } matgroup.m_DiffuseColor = Helper.BGR15ToColor((ushort)matgroup.m_DifAmbColors); matgroup.m_AmbientColor = Helper.BGR15ToColor((ushort)(matgroup.m_DifAmbColors >> 16)); matgroup.m_SpecularColor = Helper.BGR15ToColor((ushort)matgroup.m_SpeEmiColors); matgroup.m_EmissionColor = Helper.BGR15ToColor((ushort)(matgroup.m_SpeEmiColors >> 16)); switch (matgroup.m_TexParams >> 30) { case 0: matgroup.m_TexCoordScale = new Vector2(1.0f, 1.0f); matgroup.m_TexCoordRot = 0.0f; matgroup.m_TexCoordTrans = new Vector2(0.0f, 0.0f); break; case 1: { int sscale = (int)m_File.Read32(mchunkoffset + 0x0C); int tscale = (int)m_File.Read32(mchunkoffset + 0x10); short trot = (short)m_File.Read16(mchunkoffset + 0x14); int strans = (int)m_File.Read32(mchunkoffset + 0x18); int ttrans = (int)m_File.Read32(mchunkoffset + 0x1C); matgroup.m_TexCoordScale = new Vector2((float)sscale / 4096.0f, (float)tscale / 4096.0f); matgroup.m_TexCoordRot = ((float)trot * (float)Math.PI) / 2048.0f; matgroup.m_TexCoordTrans = new Vector2((float)strans / 4096.0f, (float)ttrans / 4096.0f); } break; case 2: goto case 1; case 3: goto case 1; default: break; // throw new Exception(String.Format("BMD: unsupported texture coord transform mode {0}", matgroup.m_TexParams >> 30)); } if (texid != 0xFFFFFFFF) { matgroup.m_Texture = ReadTexture(texid, palid); matgroup.m_TexParams |= matgroup.m_Texture.m_DSTexParam; } else { matgroup.m_Texture = null; } uint pchunkoffset = m_File.Read32((uint)(m_PolyChunksOffset + (polyID * 8) + 4)); uint dloffset = m_File.Read32(pchunkoffset + 0x0C); uint dlsize = m_File.Read32(pchunkoffset + 0x08); uint numbones = m_File.Read32(pchunkoffset); uint bonesoffset = m_File.Read32(pchunkoffset + 0x04); matgroup.m_BoneIDs = new ushort[numbones]; for (uint b = 0; b < numbones; b++) { byte idx1 = m_File.Read8(bonesoffset + b); matgroup.m_BoneIDs[b] = m_File.Read16((uint)(m_BoneMapOffset + (2 * idx1))); } matgroup.m_Geometry = new List <VertexList>(); m_CurVertex.m_Position = new Vector3(0, 0, 0); m_CurVertex.m_TexCoord = null; m_CurVertex.m_Normal = null; if ((matgroup.m_PolyAttribs & 0x8000) != 0x8000) { byte alpha = (byte)((matgroup.m_PolyAttribs >> 16) & 0x1F); alpha |= (byte)(alpha >> 5); matgroup.m_Alpha = alpha; } if ((matgroup.m_DifAmbColors & 0x8000) == 0x8000) { m_CurVertex.m_Color = Color.FromArgb(matgroup.m_Alpha << 3, matgroup.m_DiffuseColor); } else { m_CurVertex.m_Color = Color.Black; } m_CurVertex.m_MatrixID = 0; uint dlend = dloffset + dlsize; for (uint pos = dloffset; pos < dlend;) { byte cmd1 = m_File.Read8(pos++); byte cmd2 = m_File.Read8(pos++); byte cmd3 = m_File.Read8(pos++); byte cmd4 = m_File.Read8(pos++); ProcessGXCommand(matgroup, cmd1, ref pos); ProcessGXCommand(matgroup, cmd2, ref pos); ProcessGXCommand(matgroup, cmd3, ref pos); ProcessGXCommand(matgroup, cmd4, ref pos); } } } foreach (ModelChunk mdchunk in m_ModelChunks) { foreach (MaterialGroup matgroup in mdchunk.m_MatGroups) { matgroup.m_BoneMatrices = new Matrix4[matgroup.m_BoneIDs.Length]; for (uint b = 0; b < matgroup.m_BoneIDs.Length; b++) { matgroup.m_BoneMatrices[b] = m_ModelChunks[matgroup.m_BoneIDs[b]].m_Transform; } } } int index = 0; foreach (KeyValuePair <string, uint> entry in m_TextureIDs) { if (!m_Textures.ContainsKey(entry.Key)) { Console.WriteLine("NOT IN TEXTURES: " + entry.Key); uint palID = Math.Min(m_PaletteIDs.ElementAt(index).Value, (uint)m_PaletteIDs.Count - 1); ReadTexture(entry.Value, palID); } index++; } }
public BMD(NitroFile file) { m_File = file; m_FileName = file.m_Name; /* if (m_File.m_ID == 741) lolol = true; else*/ lolol = false; // Keep a list of pointers so it's easier to add/remove entries, space etc. m_PointerList = new List<PointerReference>(); m_ScaleFactor = (float)(1 << (int)m_File.Read32(0x0)); // ModelChunk refers to Bone m_NumModelChunks = m_File.Read32(0x04); m_ModelChunksOffset = m_File.Read32(0x08); AddPointer(0x08); for (int i = 0; i < m_NumModelChunks; i++) { AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x04)); AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x34)); AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x38)); } // PolyChunk refers to Display List m_NumPolyChunks = m_File.Read32(0x0C); m_PolyChunksOffset = m_File.Read32(0x10); AddPointer(0x10); for (int i = 0; i < m_NumPolyChunks; i++) { // Offset to Display List within Display List entries AddPointer((uint)(m_PolyChunksOffset + (i * 8) + 4)); // Offsets within the Display List 16 byte headers AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x04); AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x0C); } m_NumTexChunks = m_File.Read32(0x14); m_TexChunksOffset = m_File.Read32(0x18); m_TextureIDs = new Dictionary<string, uint>(); AddPointer(0x18); for (int i = 0; i < m_NumTexChunks; i++) { AddPointer((uint)(m_TexChunksOffset + (i * 20) + 0)); AddPointer((uint)(m_TexChunksOffset + (i * 20) + 4)); m_TextureIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_TexChunksOffset + (20 * i))), 0), (uint)i); } m_NumPalChunks = m_File.Read32(0x1C); m_PalChunksOffset = m_File.Read32(0x20); m_PaletteIDs = new Dictionary<string, uint>(); AddPointer(0x20); for (int i = 0; i < m_NumPalChunks; i++) { AddPointer((uint)(m_PalChunksOffset + (i * 16) + 0)); AddPointer((uint)(m_PalChunksOffset + (i * 16) + 4)); m_PaletteIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_PalChunksOffset + (16 * i))), 0), (uint)i); } m_NumMatChunks = m_File.Read32(0x24); m_MatChunksOffset = m_File.Read32(0x28); AddPointer(0x28); for (int i = 0; i < m_NumMatChunks; i++) { AddPointer((uint)(m_MatChunksOffset + (i * 48) + 0)); } m_BoneMapOffset = m_File.Read32(0x2C); AddPointer(0x2C); m_Textures = new Dictionary<string, Texture>(); m_ModelChunks = new ModelChunk[m_NumModelChunks]; for (uint c = 0; c < m_NumModelChunks; c++) { ModelChunk mdchunk = new ModelChunk(this); m_ModelChunks[c] = mdchunk; uint mdchunkoffset = m_ModelChunksOffset + (c * 64); mdchunk.m_ID = m_File.Read32(mdchunkoffset); mdchunk.m_Name = m_File.ReadString(m_File.Read32(mdchunkoffset + 0x04), 0); // transforms part { int xscale = (int)m_File.Read32(mdchunkoffset + 0x10); int yscale = (int)m_File.Read32(mdchunkoffset + 0x14); int zscale = (int)m_File.Read32(mdchunkoffset + 0x18); short xrot = (short)m_File.Read16(mdchunkoffset + 0x1C); short yrot = (short)m_File.Read16(mdchunkoffset + 0x1E); short zrot = (short)m_File.Read16(mdchunkoffset + 0x20); int xtrans = (int)m_File.Read32(mdchunkoffset + 0x24); int ytrans = (int)m_File.Read32(mdchunkoffset + 0x28); int ztrans = (int)m_File.Read32(mdchunkoffset + 0x2C); mdchunk.m_Scale = new Vector3((float)xscale / 4096.0f, (float)yscale / 4096.0f, (float)zscale / 4096.0f); mdchunk.m_Rotation = new Vector3(((float)xrot * (float)Math.PI) / 2048.0f, ((float)yrot * (float)Math.PI) / 2048.0f, ((float)zrot * (float)Math.PI) / 2048.0f); mdchunk.m_Translation = new Vector3((float)xtrans / 4096.0f, (float)ytrans / 4096.0f, (float)ztrans / 4096.0f); mdchunk.m_Transform = Helper.SRTToMatrix(mdchunk.m_Scale, mdchunk.m_Rotation, mdchunk.m_Translation); // Used when exporting bones mdchunk.m_20_12Scale = new uint[] { (uint)xscale, (uint)yscale, (uint)zscale }; mdchunk.m_4_12Rotation = new ushort[] { (ushort)xrot, (ushort)yrot, (ushort)zrot }; mdchunk.m_20_12Translation = new uint[] { (uint)xtrans, (uint)ytrans, (uint)ztrans }; // if the chunk has a parent, apply the parent's transform to the chunk's transform. // we don't need to go further than one level because the paren't transform already // went through its parents' transforms. short parent_offset = (short)m_File.Read16(mdchunkoffset + 0x8); if (parent_offset < 0) { int parentchunkid = (int)(c + parent_offset); Matrix4.Mult(ref mdchunk.m_Transform, ref m_ModelChunks[parentchunkid].m_Transform, out mdchunk.m_Transform); } mdchunk.m_ParentOffset = parent_offset; } // If 0x0A is set to 1 the bone has children, if 0 it doesn't mdchunk.m_HasChildren = (m_File.Read16(mdchunkoffset + 0x0A) == 1); mdchunk.m_SiblingOffset = (short)(m_File.Read16(mdchunkoffset + 0x0C)); uint flags = m_File.Read32(mdchunkoffset + 0x3C); mdchunk.m_Billboard = ((flags & 0x1) == 0x1); uint numpairs = m_File.Read32(mdchunkoffset + 0x30); uint matlist = m_File.Read32(mdchunkoffset + 0x34); uint polylist = m_File.Read32(mdchunkoffset + 0x38); mdchunk.m_MatGroups = new MaterialGroup[numpairs]; for (uint i = 0; i < numpairs; i++) { MaterialGroup matgroup = new MaterialGroup(); mdchunk.m_MatGroups[i] = matgroup; byte matID = m_File.Read8(matlist + i); byte polyID = m_File.Read8(polylist + i); uint mchunkoffset = (uint)(m_MatChunksOffset + (matID * 48)); matgroup.m_ID = matID; matgroup.m_Name = m_File.ReadString(m_File.Read32(mchunkoffset), 0); uint texid = m_File.Read32(mchunkoffset + 0x04); uint palid = m_File.Read32(mchunkoffset + 0x08); matgroup.m_TexParams = m_File.Read32(mchunkoffset + 0x20); matgroup.m_PolyAttribs = m_File.Read32(mchunkoffset + 0x24); matgroup.m_DifAmbColors = m_File.Read32(mchunkoffset + 0x28); matgroup.m_SpeEmiColors = m_File.Read32(mchunkoffset + 0x2C); if ((matgroup.m_PolyAttribs & 0x30) == 0x10) matgroup.m_TexEnvMode = TextureEnvMode.Decal; else matgroup.m_TexEnvMode = TextureEnvMode.Modulate; switch (matgroup.m_PolyAttribs & 0xC0) { case 0x00: matgroup.m_CullMode = CullFaceMode.FrontAndBack; break; case 0x40: matgroup.m_CullMode = CullFaceMode.Front; break; case 0x80: matgroup.m_CullMode = CullFaceMode.Back; break; } matgroup.m_DiffuseColor = Helper.BGR15ToColor((ushort)matgroup.m_DifAmbColors); matgroup.m_AmbientColor = Helper.BGR15ToColor((ushort)(matgroup.m_DifAmbColors >> 16)); matgroup.m_SpecularColor = Helper.BGR15ToColor((ushort)matgroup.m_SpeEmiColors); matgroup.m_EmissionColor = Helper.BGR15ToColor((ushort)(matgroup.m_SpeEmiColors >> 16)); switch (matgroup.m_TexParams >> 30) { case 0: matgroup.m_TexCoordScale = new Vector2(1.0f, 1.0f); matgroup.m_TexCoordTrans = new Vector2(0.0f, 0.0f); break; case 1: { int sscale = (int)m_File.Read32(mchunkoffset + 0x0C); int tscale = (int)m_File.Read32(mchunkoffset + 0x10); int strans = (int)m_File.Read32(mchunkoffset + 0x18); int ttrans = (int)m_File.Read32(mchunkoffset + 0x1C); matgroup.m_TexCoordScale = new Vector2((float)sscale / 4096.0f, (float)tscale / 4096.0f); matgroup.m_TexCoordTrans = new Vector2((float)strans / 4096.0f, (float)ttrans / 4096.0f); //matgroup.m_TexCoordTrans = new Vector2(0.0f, 16.0f); /*System.Windows.Forms.MessageBox.Show(String.Format("textransform: scale:{0} trans:{1} rot:{2:X8}", matgroup.m_TexCoordScale, matgroup.m_TexCoordTrans, m_File.Read32(mchunkoffset + 0x1C)));*/ } break; case 2: goto case 1; case 3: goto case 1; default: break; // throw new Exception(String.Format("BMD: unsupported texture coord transform mode {0}", matgroup.m_TexParams >> 30)); } if (texid != 0xFFFFFFFF) { matgroup.m_Texture = ReadTexture(texid, palid); matgroup.m_TexParams |= matgroup.m_Texture.m_Params; } else matgroup.m_Texture = null; uint pchunkoffset = m_File.Read32((uint)(m_PolyChunksOffset + (polyID * 8) + 4)); uint dloffset = m_File.Read32(pchunkoffset + 0x0C); uint dlsize = m_File.Read32(pchunkoffset + 0x08); uint numbones = m_File.Read32(pchunkoffset); uint bonesoffset = m_File.Read32(pchunkoffset + 0x04); matgroup.m_BoneIDs = new ushort[numbones]; for (uint b = 0; b < numbones; b++) { byte idx1 = m_File.Read8(bonesoffset + b); matgroup.m_BoneIDs[b] = m_File.Read16((uint)(m_BoneMapOffset + (2 * idx1))); } matgroup.m_Geometry = new List<VertexList>(); m_CurVertex.m_Position = new Vector3(0, 0, 0); m_CurVertex.m_TexCoord = new Vector2(0, 0); if ((matgroup.m_DifAmbColors & 0x8000) == 0x8000) { byte alpha = (byte)((matgroup.m_PolyAttribs >> 13) & 0xF8); alpha |= (byte)(alpha >> 5); matgroup.m_Alpha = alpha; m_CurVertex.m_Color = Color.FromArgb(alpha, matgroup.m_DiffuseColor); } else m_CurVertex.m_Color = Color.Black; m_CurVertex.m_MatrixID = 0; uint dlend = dloffset + dlsize; for (uint pos = dloffset; pos < dlend; ) { byte cmd1 = m_File.Read8(pos++); byte cmd2 = m_File.Read8(pos++); byte cmd3 = m_File.Read8(pos++); byte cmd4 = m_File.Read8(pos++); ProcessGXCommand(matgroup, cmd1, ref pos); ProcessGXCommand(matgroup, cmd2, ref pos); ProcessGXCommand(matgroup, cmd3, ref pos); ProcessGXCommand(matgroup, cmd4, ref pos); } } } foreach (ModelChunk mdchunk in m_ModelChunks) { foreach (MaterialGroup matgroup in mdchunk.m_MatGroups) { matgroup.m_BoneMatrices = new Matrix4[matgroup.m_BoneIDs.Length]; for (uint b = 0; b < matgroup.m_BoneIDs.Length; b++) matgroup.m_BoneMatrices[b] = m_ModelChunks[matgroup.m_BoneIDs[b]].m_Transform; } } }
char[] m_Type; // 'INFO' #endregion Fields #region Constructors public SDATInfo(NitroFile sdat, uint offset) { m_Offset = offset; m_Type = sdat.ReadString(m_Offset + 0x00, 4).ToCharArray(); m_Size = sdat.Read32(m_Offset + 0x04); m_RecordOffset = new uint[8]; for (int i = 0; i < 8; i++) m_RecordOffset[i] = sdat.Read32(m_Offset + 0x08 + (uint)(i * 4)); m_Reserved = sdat.ReadBlock(m_Offset + 0x28, 24); m_Records = new SDATInfoRecord[8]; for (int i = 0; i < 8; i++) { m_Records[i] = new SDATInfoRecord(sdat, m_Offset + m_RecordOffset[i]); } m_Records0SEQ = new SDATInfoSEQ[m_Records[0].m_Count]; for (int i = 0; i < m_Records[0].m_Count; i++) { m_Records0SEQ[i] = new SDATInfoSEQ(sdat, m_Offset + m_Records[0].m_EntryOffset[i]); } m_Records1SEQARC = new SDATInfoSEQARC[m_Records[1].m_Count]; for (int i = 0; i < m_Records[1].m_Count; i++) { m_Records1SEQARC[i] = new SDATInfoSEQARC(sdat, m_Offset + m_Records[1].m_EntryOffset[i]); } m_Records2BANK = new SDATInfoBANK[m_Records[2].m_Count]; for (int i = 0; i < m_Records[2].m_Count; i++) { m_Records2BANK[i] = new SDATInfoBANK(sdat, m_Offset + m_Records[2].m_EntryOffset[i]); } m_Records3WAVEARC = new SDATInfoWAVEARC[m_Records[3].m_Count]; for (int i = 0; i < m_Records[3].m_Count; i++) { m_Records3WAVEARC[i] = new SDATInfoWAVEARC(sdat, m_Offset + m_Records[3].m_EntryOffset[i]); } m_Records4PLAYER = new SDATInfoPLAYER[m_Records[4].m_Count]; for (int i = 0; i < m_Records[4].m_Count; i++) { m_Records4PLAYER[i] = new SDATInfoPLAYER(sdat, m_Offset + m_Records[4].m_EntryOffset[i]); } m_Records5GROUP = new SDATInfoGROUP[m_Records[5].m_Count]; for (int i = 0; i < m_Records[5].m_Count; i++) { m_Records5GROUP[i] = new SDATInfoGROUP(sdat, m_Offset + m_Records[5].m_EntryOffset[i]); } m_Records6PLAYER2 = new SDATInfoPLAYER2[m_Records[6].m_Count]; for (int i = 0; i < m_Records[6].m_Count; i++) { m_Records6PLAYER2[i] = new SDATInfoPLAYER2(sdat, m_Offset + m_Records[6].m_EntryOffset[i]); } m_Records7STREAM = new SDATInfoSTREAM[m_Records[7].m_Count]; for (int i = 0; i < m_Records[7].m_Count; i++) { m_Records7STREAM[i] = new SDATInfoSTREAM(sdat, m_Offset + m_Records[7].m_EntryOffset[i]); } }