private float[][] ConvertVertexWeights(List<odfVertex> vertexList, odfBoneList boneList) { int numBones = boneList != null ? boneList.Count : 0; float[][] vertexWeights = new float[vertexList.Count][]; for (int j = 0; j < vertexList.Count; j++) { vertexWeights[j] = new float[4]; int weightIdx = 0; for (int k = 0; k < numBones; k++) { odfBone bone = boneList[k]; for (int l = 0; l < bone.NumberIndices; l++) { if (bone.VertexIndexArray[l] == j) { vertexList[j].BoneIndices[weightIdx] = (byte)k; if (weightIdx < 3) { vertexWeights[j][weightIdx++] = bone.WeightArray[l]; } else { vertexWeights[j][3] = 1f - vertexWeights[j][0] - vertexWeights[j][1] - vertexWeights[j][2]; } break; } } } } return vertexWeights; }
public static odfBoneList CreateBoneList(ObjectID id, ObjectID meshFrameId, odfSubmesh submesh, List<ImportedBone> boneList, Matrix lMeshMatrixInv, odfFrame rootFrame) { if (boneList == null || boneList.Count == 0) return null; Dictionary<byte, Tuple<byte, odfBone>> boneDic = new Dictionary<byte, Tuple<byte, odfBone>>(boneList.Count); Tuple<List<int>, List<float>>[] newBoneListComponents = new Tuple<List<int>, List<float>>[boneList.Count]; int boneframeNotFound = 0; for (int i = 0; i < submesh.NumVertices; i++) { odfVertex vert = submesh.VertexList[i]; for (int j = 0; j < vert.BoneIndices.Length; j++) { byte boneIdx = vert.BoneIndices[j]; if (boneIdx == 0xFF) continue; Tuple<byte, odfBone> boneDesc; odfBone newBone; if (!boneDic.TryGetValue(boneIdx, out boneDesc)) { odfFrame boneFrame = odf.FindFrame(boneList[boneIdx].Name, rootFrame); if (boneFrame == null) { boneframeNotFound++; continue; } newBone = new odfBone(boneFrame.Id); newBone.Matrix = boneList[boneIdx].Matrix; boneDesc = new Tuple<byte, odfBone>((byte)boneDic.Count, newBone); boneDic.Add(boneIdx, boneDesc); newBoneListComponents[boneDesc.Item1] = new Tuple<List<int>, List<float>>(new List<int>(200), new List<float>(200)); } else newBone = boneDesc.Item2; byte newBoneIdx = boneDesc.Item1; List<int> newBoneIdxList = newBoneListComponents[newBoneIdx].Item1; newBoneIdxList.Add(i); List<float> newBoneWeightList = newBoneListComponents[newBoneIdx].Item2; newBoneWeightList.Add(vert.Weights[j]); } } if (boneDic.Count == 0) { Report.ReportLog(submesh.ToString() + ": all bones dropped because of missing skeleton."); return null; } odfBoneList newBoneList = new odfBoneList(new ObjectName(String.Empty, null), id, boneDic.Count); newBoneList.MeshFrameId = meshFrameId; newBoneList.SubmeshId = submesh.Id; newBoneList.AlwaysZero4 = new byte[4]; foreach (Tuple<byte, odfBone> boneDesc in boneDic.Values) { byte newBoneIdx = boneDesc.Item1; List<int> newBoneIdxList = newBoneListComponents[newBoneIdx].Item1; List<float> newBoneWeightList = newBoneListComponents[newBoneIdx].Item2; odfBone newBone = boneDesc.Item2; newBone.AlwaysZero24perIndex = new byte[24 * newBoneIdxList.Count]; newBone.VertexIndexArray = newBoneIdxList.ToArray(); newBone.WeightArray = newBoneWeightList.ToArray(); Matrix lMatrix = Matrix.Invert(newBone.Matrix); newBone.Matrix = Matrix.Invert(lMatrix * lMeshMatrixInv); newBoneList.AddChild(newBone); } if (boneframeNotFound > 0) Report.ReportLog(submesh.ToString() + ": " + boneframeNotFound + " bone(s) because of missing boneframe(s) dropped."); return newBoneList; }