/// <summary> /// Reads a vertex influence array for given mesh name and subindex /// returns null if not found /// </summary> /// <param name="meshName"></param> /// <param name="subIndex"></param> /// <returns></returns> public SsbhVertexInfluence[] ReadRiggingBuffer(string meshName, int subIndex) { MeshRiggingGroup riggingGroup = FindRiggingGroup(meshName, subIndex); if (riggingGroup == null) { return(new SsbhVertexInfluence[0]); } List <SsbhVertexInfluence> influences = new List <SsbhVertexInfluence>(); foreach (MeshBoneBuffer boneBuffer in riggingGroup.Buffers) { using (BinaryReader r = new BinaryReader(new MemoryStream(boneBuffer.Data))) { for (int i = 0; i < boneBuffer.Data.Length / 6; i++) { influences.Add(new SsbhVertexInfluence() { BoneName = boneBuffer.BoneName, VertexIndex = r.ReadUInt16(), Weight = r.ReadSingle() }); } } } return(influences.ToArray()); }
/// <summary> /// Reads a vertex influence array for given mesh name and subindex /// returns null if not found /// </summary> /// <param name="meshName"></param> /// <param name="subIndex"></param> /// <returns></returns> public SsbhVertexInfluence[] ReadRiggingBuffer(string meshName, int subIndex) { MeshRiggingGroup riggingGroup = meshFile.RiggingBuffers .Where(b => b.MeshName == meshName && b.MeshSubIndex == subIndex) .FirstOrDefault(); if (riggingGroup == null) { return(new SsbhVertexInfluence[0]); } List <SsbhVertexInfluence> influences = new List <SsbhVertexInfluence>(); foreach (MeshBoneBuffer boneBuffer in riggingGroup.Buffers) { using (BinaryReader r = new BinaryReader(new MemoryStream(boneBuffer.Data))) { for (int i = 0; i < boneBuffer.Data.Length / 6; i++) { influences.Add(new SsbhVertexInfluence() { BoneName = boneBuffer.BoneName, // TODO: Read an array of influence structs and store the string separately? VertexIndex = r.ReadUInt16(), Weight = r.ReadSingle() }); } } } return(influences.ToArray()); }
/// <summary> /// Finds a rigging group for given mesh name and sub index /// </summary> /// <param name="meshName"></param> /// <param name="subIndex"></param> /// <returns>null if not found</returns> private MeshRiggingGroup FindRiggingGroup(string meshName, int subIndex) { MeshRiggingGroup riggingGroup = null; foreach (MeshRiggingGroup g in meshFile.RiggingBuffers) { if (g.Name.Equals(meshName) && g.SubMeshIndex == subIndex) { riggingGroup = g; break; } } return(riggingGroup); }
/// <summary> /// Creates a mesh rigging group /// </summary> /// <param name="meshName"></param> /// <param name="meshIndex"></param> /// <param name="influences"></param> /// <returns></returns> public static MeshRiggingGroup CreateRiggingGroup(string meshName, int meshIndex, SSBHVertexInfluence[] influences) { var group = new MeshRiggingGroup { Name = meshName, SubMeshIndex = meshIndex }; Dictionary <string, List <byte> > boneNameToData = new Dictionary <string, List <byte> >(); Dictionary <ushort, int> vertexToWeightCount = new Dictionary <ushort, int>(); int MaxInfluenceCount = 0; foreach (var influence in influences) { // get byte list if (!boneNameToData.ContainsKey(influence.BoneName)) { boneNameToData.Add(influence.BoneName, new List <byte>()); } var bytes = boneNameToData[influence.BoneName]; bytes.AddRange(BitConverter.GetBytes(influence.VertexIndex)); bytes.AddRange(BitConverter.GetBytes(influence.Weight)); if (!vertexToWeightCount.ContainsKey(influence.VertexIndex)) { vertexToWeightCount.Add(influence.VertexIndex, 0); } vertexToWeightCount[influence.VertexIndex]++; MaxInfluenceCount = Math.Max(MaxInfluenceCount, vertexToWeightCount[influence.VertexIndex]); } // create bone groups group.Flags = 0x0100 | MaxInfluenceCount; List <MeshBoneBuffer> bonebuffers = new List <MeshBoneBuffer>(); foreach (var pair in boneNameToData) { bonebuffers.Add(new MeshBoneBuffer() { BoneName = pair.Key, Data = pair.Value.ToArray() }); } group.Buffers = bonebuffers.ToArray().OrderBy(o => o.BoneName, StringComparer.Ordinal).ToArray(); return(group); }
public SSBHVertexInfluence[] ReadRiggingBuffer(string MeshName, int SubIndex) { MeshRiggingGroup riggingGroup = null; foreach (MeshRiggingGroup g in MeshFile.RiggingBuffers) { if (g.Name.Equals(MeshName) && g.SubMeshIndex == SubIndex) { riggingGroup = g; break; } } if (riggingGroup == null) { return(new SSBHVertexInfluence[0]); } List <SSBHVertexInfluence> Influences = new List <SSBHVertexInfluence>(); foreach (MeshBoneBuffer boneBuffer in riggingGroup.Buffers) { using (BinaryReader R = new BinaryReader(new MemoryStream(boneBuffer.Data))) { for (int i = 0; i < boneBuffer.Data.Length / 6; i++) { Influences.Add(new SSBHVertexInfluence() { BoneName = boneBuffer.BoneName, VertexIndex = R.ReadUInt16(), Weight = R.ReadSingle() }); } } } return(Influences.ToArray()); }