public void SetBoneMatrix(int meshId, int boneId, double m11, double m12, double m13, double m14, double m21, double m22, double m23, double m24, double m31, double m32, double m33, double m34, double m41, double m42, double m43, double m44) { xxBone bone = Meshes[meshId].Mesh.BoneList[boneId]; Matrix m = new Matrix(); m.M11 = (float)m11; m.M12 = (float)m12; m.M13 = (float)m13; m.M14 = (float)m14; m.M21 = (float)m21; m.M22 = (float)m22; m.M23 = (float)m23; m.M24 = (float)m24; m.M31 = (float)m31; m.M32 = (float)m32; m.M33 = (float)m33; m.M34 = (float)m34; m.M41 = (float)m41; m.M42 = (float)m42; m.M43 = (float)m43; m.M44 = (float)m44; bone.Matrix = m; }
public void SetBoneSRT(int meshId, int boneId, double sX, double sY, double sZ, double rX, double rY, double rZ, double tX, double tY, double tZ) { xxBone bone = Meshes[meshId].Mesh.BoneList[boneId]; bone.Matrix = FbxUtility.SRTToMatrix(new Vector3((float)sX, (float)sY, (float)sZ), new Vector3((float)rX, (float)rY, (float)rZ), new Vector3((float)tX, (float)tY, (float)tZ)); Changed = true; }
public bool RenameSkeletonProfile(string pattern, string replacement) { bool anyRenaming = false; for (int i = 0; i < Frames.Count; i++) { xxFrame frame = Frames[i]; string name = System.Text.RegularExpressions.Regex.Replace(frame.Name, pattern, replacement, System.Text.RegularExpressions.RegexOptions.IgnoreCase); if (name != frame.Name) { SetFrameName(i, name); Changed = true; anyRenaming = true; } } if (anyRenaming) { for (int i = 0; i < Meshes.Count; i++) { xxFrame meshFrame = Meshes[i]; for (int j = 0; j < meshFrame.Mesh.BoneList.Count; j++) { xxBone bone = meshFrame.Mesh.BoneList[j]; string name = System.Text.RegularExpressions.Regex.Replace(bone.Name, pattern, replacement, System.Text.RegularExpressions.RegexOptions.IgnoreCase); if (name != bone.Name) { SetBoneName(i, j, name); Changed = true; anyRenaming = true; } } } } return(anyRenaming); }
public static List <xxBone> MergeBoneList(List <xxBone> boneList1, List <xxBone> boneList2, out byte[] boneList2IdxMap) { boneList2IdxMap = new byte[boneList2.Count]; Dictionary <string, int> boneDic = new Dictionary <string, int>(); List <xxBone> mergedList = new List <xxBone>(boneList1.Count + boneList2.Count); for (int i = 0; i < boneList1.Count; i++) { xxBone xxBone = boneList1[i].Clone(); boneDic.Add(xxBone.Name, i); mergedList.Add(xxBone); } for (int i = 0; i < boneList2.Count; i++) { xxBone xxBone = boneList2[i].Clone(); int boneIdx; if (boneDic.TryGetValue(xxBone.Name, out boneIdx)) { mergedList[boneIdx] = xxBone; } else { boneIdx = mergedList.Count; mergedList.Add(xxBone); boneDic.Add(xxBone.Name, boneIdx); } xxBone.Index = boneIdx; boneList2IdxMap[i] = (byte)boneIdx; } return(mergedList); }
public xxBone Clone() { xxBone bone = new xxBone(); bone.Name = Name; bone.Index = Index; bone.Matrix = Matrix; return(bone); }
public void SetBoneName(int meshId, int boneId, string name) { List <xxBone> boneList = Meshes[meshId].Mesh.BoneList; xxBone bone = xx.FindBone(boneList, name); if (bone != null) { throw new Exception("Bone with this name is already in the bonelist"); } bone = boneList[boneId]; bone.Name = name; Changed = true; }
public static List <xxBone> CreateBoneList(List <ImportedBone> boneList) { List <xxBone> xxBoneList = new List <xxBone>(boneList.Count); for (int i = 0; i < boneList.Count; i++) { xxBone xxBone = new xxBone(); xxBone.Name = boneList[i].Name; xxBone.Matrix = boneList[i].Matrix; xxBone.Index = i; xxBoneList.Add(xxBone); } return(xxBoneList); }
public static void RemoveUnusedBones(List <List <xxVertex> > vertexLists, List <xxBone> boneList) { byte[] boneMap = null; bool skinnedStart = (boneList.Count > 0); if (skinnedStart) { bool[] bonesUsed = IsBoneUsedList(vertexLists, boneList); boneMap = new byte[boneList.Count]; int numRemoved = 0; for (int i = 0; i < bonesUsed.Length; i++) { int removeIdx = i - numRemoved; if (bonesUsed[i]) { boneMap[i] = (byte)removeIdx; xxBone bone = boneList[removeIdx]; bone.Index = removeIdx; } else { boneList.RemoveAt(removeIdx); numRemoved++; } } } bool skinnedEnd = (boneList.Count > 0); if (skinnedStart && skinnedEnd) { foreach (var vertList in vertexLists) { UpdateBoneIndices(vertList, boneMap); } } else if (skinnedStart && !skinnedEnd) { // skinned -> unskinned foreach (var vertList in vertexLists) { foreach (var vert in vertList) { vert.BoneIndices = new byte[4]; vert.Weights3 = new float[3]; } } } }
public void CopyBone(int meshId, int boneId) { xxFrame frame = Meshes[meshId]; List <xxBone> boneList = frame.Mesh.BoneList; xxBone root = xx.FindBone(boneList, Frames[0].Name); if (root != null) { throw new Exception("One bone already targets the root frame."); } xxBone copy = boneList[boneId].Clone(); copy.Name = Frames[0].Name; boneList.Add(copy); }
protected List <xxBone> ParseBoneList() { int numBones = reader.ReadInt32(); List <xxBone> boneList = new List <xxBone>(numBones); for (int i = 0; i < numBones; i++) { xxBone bone = new xxBone(); boneList.Add(bone); bone.Name = reader.ReadName(); bone.Index = reader.ReadInt32(); bone.Matrix = reader.ReadMatrix(); } return(boneList); }
public void ZeroWeights(int meshId, int boneId) { xxMesh mesh = Meshes[meshId].Mesh; xxBone bone = mesh.BoneList[boneId]; xxFrame parentFrame = xx.FindFrame(bone.Name, Parser.Frame).Parent; xxBone parentBone = xx.FindBone(mesh.BoneList, parentFrame.Name); byte parentBoneIdx = (byte)mesh.BoneList.IndexOf(parentBone); foreach (xxSubmesh submesh in mesh.SubmeshList) { foreach (xxVertex vertex in submesh.VertexList) { int parentIdx = -1; for (int i = 0; i < vertex.BoneIndices.Length; i++) { if (vertex.BoneIndices[i] == parentBoneIdx) { parentIdx = i; break; } } for (int i = 0; i < vertex.BoneIndices.Length; i++) { if (vertex.BoneIndices[i] == boneId) { if (parentIdx >= 0) { float[] w4 = vertex.Weights4(true); w4[parentIdx] += w4[i]; w4[i] = 0; vertex.Weights3[0] = w4[0]; vertex.Weights3[1] = w4[1]; vertex.Weights3[2] = w4[2]; } else { vertex.BoneIndices[i] = parentBoneIdx; } break; } } } } Changed = true; }
private AnimationFrame CreateFrame(xxFrame frame, xxParser parser, HashSet <string> extractFrames, HashSet <string> meshNames, Device device, Matrix combinedParent, List <AnimationFrame> meshFrames) { AnimationFrame animationFrame = new AnimationFrame(); animationFrame.Name = frame.Name; animationFrame.TransformationMatrix = frame.Matrix; animationFrame.OriginalTransform = animationFrame.TransformationMatrix; animationFrame.CombinedTransform = combinedParent * animationFrame.TransformationMatrix; xxMesh mesh = frame.Mesh; if (meshNames.Contains(frame.Name) && (mesh != null)) { List <xxBone> boneList = mesh.BoneList; string[] boneNames = new string[boneList.Count]; Matrix[] boneOffsets = new Matrix[boneList.Count]; for (int i = 0; i < boneList.Count; i++) { xxBone bone = boneList[i]; boneNames[i] = bone.Name; boneOffsets[i] = bone.Matrix; } AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[mesh.SubmeshList.Count]; Vector3 min = new Vector3(Single.MaxValue); Vector3 max = new Vector3(Single.MinValue); for (int i = 0; i < mesh.SubmeshList.Count; i++) { xxSubmesh submesh = mesh.SubmeshList[i]; List <xxFace> faceList = submesh.FaceList; List <xxVertex> vertexList = submesh.VertexList; Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format); using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None)) { for (int j = 0; j < faceList.Count; j++) { ushort[] indices = faceList[j].VertexIndices; indexStream.Write(indices[0]); indexStream.Write(indices[2]); indexStream.Write(indices[1]); } animationMesh.UnlockIndexBuffer(); } FillVertexBuffer(animationMesh, vertexList, -1); var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2]; for (int j = 0; j < vertexList.Count; j++) { xxVertex vertex = vertexList[j]; normalLines[j * 2] = new PositionBlendWeightsIndexedColored(vertex.Position, vertex.Weights3, vertex.BoneIndices, Color.Yellow.ToArgb()); normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(vertex.Position + (vertex.Normal / 16), vertex.Weights3, vertex.BoneIndices, Color.Yellow.ToArgb()); min = Vector3.Minimize(min, vertex.Position); max = Vector3.Maximize(max, vertex.Position); } AnimationMeshContainer meshContainer = new AnimationMeshContainer(); meshContainer.Name = animationFrame.Name; meshContainer.MeshData = new MeshData(animationMesh); meshContainer.NormalLines = normalLines; meshContainers[i] = meshContainer; int matIdx = submesh.MaterialIndex; if ((matIdx >= 0) && (matIdx < parser.MaterialList.Count)) { int texIdx; if (!MatTexIndices.TryGetValue(matIdx, out texIdx)) { texIdx = -1; xxMaterial mat = parser.MaterialList[matIdx]; Material materialD3D = new Material(); materialD3D.Ambient = mat.Ambient; materialD3D.Diffuse = mat.Diffuse; materialD3D.Emissive = mat.Emissive; materialD3D.Specular = mat.Specular; materialD3D.Power = mat.Power; Materials[matIdx] = materialD3D; xxMaterialTexture matTex = mat.Textures[0]; string matTexName = matTex.Name; if (matTexName != String.Empty) { for (int j = 0; j < parser.TextureList.Count; j++) { xxTexture tex = parser.TextureList[j]; if (tex.Name == matTexName) { texIdx = j; if (Textures[j] == null) { ImportedTexture importedTex = xx.ImportedTexture(tex); Textures[j] = Texture.FromMemory(device, importedTex.Data); } break; } } } MatTexIndices.Add(matIdx, texIdx); } meshContainer.MaterialIndex = matIdx; meshContainer.TextureIndex = texIdx; } } for (int i = 0; i < (meshContainers.Length - 1); i++) { meshContainers[i].NextMeshContainer = meshContainers[i + 1]; } for (int i = 0; i < meshContainers.Length; i++) { meshContainers[i].BoneNames = boneNames; meshContainers[i].BoneOffsets = boneOffsets; } min = Vector3.TransformCoordinate(min, animationFrame.CombinedTransform); max = Vector3.TransformCoordinate(max, animationFrame.CombinedTransform); animationFrame.Bounds = new BoundingBox(min, max); animationFrame.MeshContainer = meshContainers[0]; meshFrames.Add(animationFrame); } for (int i = 0; i < frame.Count; i++) { xxFrame child = frame[i]; if (extractFrames.Contains(child.Name)) { AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, meshNames, device, animationFrame.CombinedTransform, meshFrames); childAnimationFrame.Parent = animationFrame; animationFrame.AppendChild(childAnimationFrame); } } numFrames++; return(animationFrame); }
public void SetBoneName(int meshId, int boneId, string name) { xxBone bone = Meshes[meshId].Mesh.BoneList[boneId]; bone.Name = name; }
public void RemoveBone(int meshId, int boneId) { xxFrame frame = Meshes[meshId]; xxFrame boneFrame = xx.FindFrame(frame.Mesh.BoneList[boneId].Name, Parser.Frame); xxBone parentBone = null; if (boneFrame != null) { xxFrame parentFrame = boneFrame.Parent; parentBone = xx.FindBone(frame.Mesh.BoneList, parentFrame.Name); } frame.Mesh.BoneList.RemoveAt(boneId); for (int i = boneId; i < frame.Mesh.BoneList.Count; i++) { xxBone bone = frame.Mesh.BoneList[i]; bone.Index--; } byte parentBoneIdx = (byte)frame.Mesh.BoneList.IndexOf(parentBone); foreach (xxSubmesh submesh in frame.Mesh.SubmeshList) { foreach (xxVertex vertex in submesh.VertexList) { for (int i = 0; i < vertex.BoneIndices.Length; i++) { byte boneIdx = vertex.BoneIndices[i]; if (boneIdx == boneId) { float[] w4 = vertex.Weights4(true); for (int j = i + 1; j < vertex.BoneIndices.Length; j++) { vertex.BoneIndices[j - 1] = vertex.BoneIndices[j]; vertex.Weights3[j - 1] = w4[j]; } vertex.BoneIndices[vertex.BoneIndices.Length - 1] = 0xFF; w4 = vertex.Weights4(true); float normalize = 1f / (w4[0] + w4[1] + w4[2] + w4[3]); if (w4[3] != 1f) { for (int j = 0; vertex.BoneIndices[j] != 0xFF; j++) { vertex.Weights3[j] *= normalize; } } else if (parentBoneIdx >= 0) { vertex.BoneIndices[0] = parentBoneIdx; vertex.Weights3[0] = 1f; } i--; } else if (boneIdx != 0xFF && boneIdx > boneId) { vertex.BoneIndices[i]--; } } } } if (frame.Mesh.VertexListDuplicate.Count > 0) { frame.Mesh.VertexListDuplicate = xx.CreateVertexListDup(frame.Mesh.SubmeshList); } Changed = true; }