public static remSkin CreateBoneList(ImportedMesh mesh, Matrix lMeshMatrixInv) { if (mesh.BoneList == null || mesh.BoneList.Count == 0) { return(null); } Dictionary <int, float>[] boneDic = new Dictionary <int, float> [mesh.BoneList.Count]; for (int i = 0; i < mesh.BoneList.Count; i++) { boneDic[i] = new Dictionary <int, float>(); } int vertexOffset = 0; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { List <ImportedVertex> vertices = submesh.VertexList; for (int i = 0; i < vertices.Count; i++) { ImportedVertex vert = vertices[i]; for (int j = 0; j < vert.BoneIndices.Length; j++) { if (vert.BoneIndices[j] == 0xFF) { continue; } boneDic[vert.BoneIndices[j]].Add(vertexOffset + i, vert.Weights[j]); } } vertexOffset += vertices.Count; } remSkin remBoneList = new remSkin(mesh.BoneList.Count); remBoneList.mesh = new remId(mesh.Name); Vector3 scale, translate; Quaternion rotate; lMeshMatrixInv.Decompose(out scale, out rotate, out translate); scale.X = Math.Abs(scale.X); scale.Y = Math.Abs(scale.Y); scale.Z = Math.Abs(scale.Z); Matrix combinedCorrection = Matrix.Scaling(-1f / scale.X, 1f / scale.Y, -1f / scale.Z) * lMeshMatrixInv; for (int i = 0; i < mesh.BoneList.Count; i++) { remBoneWeights boneWeights = new remBoneWeights(); boneWeights.bone = new remId(mesh.BoneList[i].Name); Matrix lMatrix = Matrix.Invert(mesh.BoneList[i].Matrix); boneWeights.matrix = Matrix.Invert(lMatrix * combinedCorrection); boneWeights.vertexIndices = new int[boneDic[i].Count]; boneDic[i].Keys.CopyTo(boneWeights.vertexIndices, 0); boneWeights.vertexWeights = new float[boneDic[i].Count]; boneDic[i].Values.CopyTo(boneWeights.vertexWeights, 0); remBoneList.AddChild(boneWeights); } return(remBoneList); }
public void CopyBoneWeights(int meshIdx, int boneIdx) { remMesh mesh = Parser.MESC[meshIdx]; remSkin skin = rem.FindSkin(mesh.name, Parser.SKIC); remBoneWeights boneWeights = skin[boneIdx]; skin.AddChild(boneWeights.Clone()); }
public remSkin Clone() { remSkin skin = new remSkin(Count); foreach (remBoneWeights boneWeights in this) { skin.AddChild(boneWeights.Clone()); } return(skin); }
public remMesh CreateMesh(out remSkin skin) { remMesh mesh = new remMesh(Count); skin = new remSkin(0); skin.mesh = mesh.name = name; List <remVertex> newVertices = new List <remVertex>(); List <int> newFaces = new List <int>(); List <int> newFaceMarks = new List <int>(); Dictionary <remId, Tuple <Matrix, List <int>, List <float> > > boneDic = new Dictionary <remId, Tuple <Matrix, List <int>, List <float> > >(); for (int i = 0; i < Count; i++) { Submesh submesh = this[i]; mesh.AddMaterial(submesh.MaterialName); newFaces.Capacity += submesh.FaceList.Count; foreach (int vertexIdx in submesh.FaceList) { newFaces.Add(newVertices.Count + vertexIdx); } int[] faceMarks = new int[submesh.numFaces]; for (int j = 0; j < submesh.numFaces; j++) { faceMarks[j] = i; } newFaceMarks.AddRange(faceMarks); if (submesh.BoneList != null) { foreach (remBoneWeights boneWeights in submesh.BoneList) { Tuple <Matrix, List <int>, List <float> > newBone = null; if (!boneDic.TryGetValue(boneWeights.bone, out newBone)) { newBone = new Tuple <Matrix, List <int>, List <float> >(boneWeights.matrix, new List <int>(boneWeights.numVertIdxWts), new List <float>(boneWeights.numVertIdxWts)); boneDic.Add(boneWeights.bone, newBone); } List <int> vertIdxs = newBone.Item2; vertIdxs.Capacity += boneWeights.vertexIndices.Length; foreach (int vertexIdx in boneWeights.vertexIndices) { vertIdxs.Add(newVertices.Count + vertexIdx); } List <float> weights = newBone.Item3; weights.AddRange(boneWeights.vertexWeights); } } newVertices.AddRange(submesh.VertexList); } mesh.vertices = newVertices.ToArray(); mesh.faces = newFaces.ToArray(); mesh.faceMarks = newFaceMarks.ToArray(); foreach (var pair in boneDic) { remBoneWeights newBoneWeights = new remBoneWeights(); newBoneWeights.bone = pair.Key; newBoneWeights.matrix = pair.Value.Item1; newBoneWeights.vertexIndices = pair.Value.Item2.ToArray(); newBoneWeights.vertexWeights = pair.Value.Item3.ToArray(); skin.AddChild(newBoneWeights); } return(mesh); }
private static remSKICsection ReadSkin(string sectionName, int sectionLength, int numSkins, byte[] sectionBuffer) { remSKICsection skinSec = new remSKICsection(numSkins); int secBufIdx = 0; for (int subSection = 0; subSection < numSkins; subSection++) { byte[] type = new byte[4] { sectionBuffer[secBufIdx + 0], sectionBuffer[secBufIdx + 1], sectionBuffer[secBufIdx + 2], sectionBuffer[secBufIdx + 3] }; int length = BitConverter.ToInt32(sectionBuffer, secBufIdx + 4); remId mesh = GetIdentifier(sectionBuffer, secBufIdx + 8); int numWeights = BitConverter.ToInt32(sectionBuffer, secBufIdx + 8 + 256); remSkin skin = new remSkin(numWeights); Trace.Assert(TypeCheck(remSkin.ClassType, type)); skin.mesh = mesh; int weightBufIdx = secBufIdx + 8 + 256 + 4; for (int weightIdx = 0; weightIdx < numWeights; weightIdx++) { remBoneWeights weights = new remBoneWeights(); weights.bone = GetIdentifier(sectionBuffer, weightBufIdx); weightBufIdx += 256; int numVertIdxWts = BitConverter.ToInt32(sectionBuffer, weightBufIdx); weightBufIdx += 4; Matrix matrix = new Matrix(); for (int i = 0; i < 4; i++) { Vector4 row = new Vector4(); for (int j = 0; j < 4; j++) { row[j] = BitConverter.ToSingle(sectionBuffer, weightBufIdx); weightBufIdx += 4; } matrix.set_Rows(i, row); } weights.matrix = matrix; weights.vertexIndices = new int[numVertIdxWts]; for (int i = 0; i < numVertIdxWts; i++) { weights.vertexIndices[i] = BitConverter.ToInt32(sectionBuffer, weightBufIdx); weightBufIdx += 4; } weights.vertexWeights = new float[weights.numVertIdxWts]; for (int i = 0; i < numVertIdxWts; i++) { weights.vertexWeights[i] = BitConverter.ToSingle(sectionBuffer, weightBufIdx); weightBufIdx += 4; } skin.AddChild(weights); } skinSec.AddChild(skin); secBufIdx += length; } if (secBufIdx != sectionLength) { Report.ReportLog("Warning! SKIC section has wrong length."); } return(skinSec); }