public static void CopyOrCreateUnknowns(odfFrame dest, odfParser parser) { odfFrame src = FindFrame(dest.Name, parser.FrameSection.RootFrame); if (src == null) { dest.Id = parser.GetNewID(typeof(odfFrame)); CreateUnknowns(dest); } else { dest.Id = new ObjectID(src.Id); CopyUnknowns(src, dest); } for (int i = 0; i < dest.Count; i++) { CopyOrCreateUnknowns(dest[i], parser); } }
public void AddFrame(odfFrame srcFrame, odfParser srcParser, int destParentIdx) { List<ObjectID> meshIDs = new List<ObjectID>(); odfFrame newFrame = srcFrame.Clone(true, meshIDs, true); AddFrame(newFrame, destParentIdx); string boneWarning = String.Empty; foreach (ObjectID meshID in meshIDs) { odfMesh srcMesh = odf.FindMeshListSome(meshID, srcParser.MeshSection); odfMesh mesh = srcMesh.Clone(); Parser.MeshSection.AddChild(mesh); if (srcParser.EnvelopeSection != null) { foreach (odfSubmesh submesh in mesh) { odfBoneList boneList = odf.FindBoneList(submesh.Id, srcParser.EnvelopeSection); if (boneList != null) { if (Parser.EnvelopeSection != null) { odfBoneList copy = boneList.Clone(); Parser.EnvelopeSection.AddChild(copy); } else { boneWarning += (boneWarning != String.Empty ? ", " : "") + mesh.ToString(); break; } } } } } Parser.CollectObjectIDs(); if (boneWarning != String.Empty) Report.ReportLog("Warning! Bones of " + boneWarning + " dropped because the destination had no Envelope section."); }
private AnimationFrame CreateFrame(odfFrame frame, odfParser parser, HashSet<int> extractFrames, HashSet<int> meshIDs, 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; if ((int)frame.MeshId != 0 && meshIDs.Contains((int)frame.MeshId)) { odfMesh mesh = odf.FindMeshListSome(frame.MeshId, parser.MeshSection); ExtendedMaterial[] materials = new ExtendedMaterial[mesh.Count]; AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[mesh.Count]; Vector3 min = new Vector3(Single.MaxValue); Vector3 max = new Vector3(Single.MinValue); for (int i = 0; i < mesh.Count; i++) { odfSubmesh submesh = mesh[i]; List<odfFace> faceList = submesh.FaceList; List<odfVertex> vertexList = submesh.VertexList; odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection); bool skinned = boneList != null; int numBones = skinned ? boneList.Count : 0; string[] boneNames = new string[numBones]; Matrix[] boneOffsets = new Matrix[numBones]; for (int boneIdx = 0; boneIdx < numBones; boneIdx++) { odfBone bone = boneList[boneIdx]; boneNames[boneIdx] = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name; Matrix mirrored; if (!BoneMatrixDic.TryGetValue(boneNames[boneIdx], out mirrored)) { #if !DONT_MIRROR Vector3 translate, scale; Quaternion rotate; bone.Matrix.Decompose(out scale, out rotate, out translate); mirrored = Matrix.Scaling(scale.X, scale.Y, -scale.Z) * Matrix.RotationQuaternion(rotate) * Matrix.Translation(translate); #else mirrored = bone.Matrix; #endif BoneMatrixDic.Add(boneNames[boneIdx], mirrored); } boneOffsets[boneIdx] = mirrored; } 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[1]); indexStream.Write(indices[2]); } animationMesh.UnlockIndexBuffer(); } float[][] vertexWeights = ConvertVertexWeights(vertexList, boneList); FillVertexBuffer(animationMesh, vertexList, vertexWeights, -1); var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2]; for (int j = 0; j < vertexList.Count; j++) { odfVertex vertex = vertexList[j]; #if !DONT_MIRROR Vector3 position = new Vector3(vertex.Position.X, vertex.Position.Y, -vertex.Position.Z); Vector3 normal = new Vector3(vertex.Normal.X, vertex.Normal.Y, -vertex.Normal.Z); #else Vector3 position = vertex.Position; Vector3 normal = vertex.Normal; #endif float[] boneWeights = vertexWeights[j]; normalLines[j * 2] = new PositionBlendWeightsIndexedColored(position, boneWeights, vertex.BoneIndices, Color.Yellow.ToArgb()); normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + (normal / 11), boneWeights, vertex.BoneIndices, Color.Blue.ToArgb()); min = Vector3.Minimize(min, position); max = Vector3.Maximize(max, position); } AnimationMeshContainer meshContainer = new AnimationMeshContainer(); meshContainer.Name = animationFrame.Name; meshContainer.MeshData = new MeshData(animationMesh); meshContainer.NormalLines = normalLines; meshContainer.BoneNames = boneNames; meshContainer.BoneOffsets = boneOffsets; meshContainers[i] = meshContainer; odfMaterial mat = odf.FindMaterialInfo(submesh.MaterialId, parser.MaterialSection); if (mat != null) { Material material3D = new Material(); material3D.Ambient = mat.Ambient; material3D.Diffuse = mat.Diffuse; material3D.Emissive = mat.Emissive; material3D.Specular = mat.Specular; material3D.Power = mat.SpecularPower; int matIdx = parser.MaterialSection.IndexOf(mat); Materials[matIdx] = material3D; meshContainer.MaterialIndex = matIdx; int texIdx = -1; if ((int)submesh.TextureIds[0] != 0 && !TextureDic.TryGetValue((int)submesh.TextureIds[0], out texIdx)) { odfTexture tex = odf.FindTextureInfo(submesh.TextureIds[0], parser.TextureSection); if (tex != null) { try { odfTextureFile texFile = new odfTextureFile(null, Path.GetDirectoryName(parser.ODFPath) + Path.DirectorySeparatorChar + tex.TextureFile); int fileSize = 0; ImportedTexture impTex = new ImportedTexture(texFile.DecryptFile(ref fileSize).BaseStream, tex.TextureFile); Texture memTex = impTex.ToTexture(device); texIdx = TextureDic.Count; TextureDic.Add((int)submesh.TextureIds[0], texIdx); Textures[texIdx] = memTex; } catch (SlimDXException ex) { Utility.ReportException(ex); Report.ReportLog("Please check " + tex.TextureFile + ". It may have an unsupported format."); } catch (Exception ex) { Utility.ReportException(ex); } } } meshContainer.TextureIndex = texIdx; } } for (int i = 0; i < (meshContainers.Length - 1); i++) { meshContainers[i].NextMeshContainer = meshContainers[i + 1]; } animationFrame.Bounds = new BoundingBox(min, max); animationFrame.MeshContainer = meshContainers[0]; meshFrames.Add(animationFrame); } for (int i = 0; i < frame.Count; i++) { odfFrame child = frame[i]; if (extractFrames.Contains((int)child.Id)) { AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, meshIDs, device, animationFrame.CombinedTransform, meshFrames); childAnimationFrame.Parent = animationFrame; animationFrame.AppendChild(childAnimationFrame); } } numFrames++; return animationFrame; }
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; }
public static void ReplaceMesh(odfFrame frame, odfParser parser, WorkspaceMesh mesh, List<ImportedMaterial> materials, List<ImportedTexture> textures, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod) { Matrix transform = Matrix.Identity; odfFrame transformFrame = frame; while (transformFrame != null) { transform *= transformFrame.Matrix; transformFrame = transformFrame.Parent as odfFrame; } transform.Invert(); string[] materialNames; int[] indices; bool[] worldCoords; bool[] replaceSubmeshesOption; odfMesh newMesh = CreateMesh(mesh, parser.MeshSection._FormatType, out materialNames, out indices, out worldCoords, out replaceSubmeshesOption); odfMesh frameMesh = odf.FindMeshListSome(frame.MeshId, parser.MeshSection); if (frameMesh != null) { if (parser.UsedIDs == null) // prevent misleading error message { parser.CollectObjectIDs(); } newMesh.Id = frameMesh.Id; newMesh.Name = frameMesh.Name; parser.MeshSection.InsertChild(parser.MeshSection.IndexOf(frameMesh), newMesh); } else { newMesh.Id = parser.GetNewID(typeof(odfMesh)); frame.MeshId = newMesh.Id; parser.MeshSection.AddChild(newMesh); } Dictionary<ObjectID, ObjectID> submeshIDtranslation = new Dictionary<ObjectID, ObjectID>(newMesh.Count); odfSubmesh[] replaceSubmeshes = frameMesh != null ? new odfSubmesh[frameMesh.Count] : null; List<odfSubmesh> addSubmeshes = new List<odfSubmesh>(newMesh.Count); for (int i = 0; i < newMesh.Count; i++) { ObjectID[] texIDs = new ObjectID[4] { ObjectID.INVALID, ObjectID.INVALID, ObjectID.INVALID, ObjectID.INVALID }; odfMaterial mat = odf.FindMaterialInfo(materialNames[i], parser.MaterialSection); if (materials != null && mat == null) { ImportedMaterial impMat = ImportedHelpers.FindMaterial(materialNames[i], materials); if (impMat != null) { mat = CreateMaterial(impMat, parser.GetNewID(typeof(odfMaterial))); parser.MaterialSection.AddChild(mat); for (int j = 0; j < impMat.Textures.Length; j++) { string texName = impMat.Textures[j]; odfTexture tex = odf.FindTextureInfo(texName, parser.TextureSection); if (tex == null) { ImportedTexture impTex = ImportedHelpers.FindTexture(texName, textures); if (impTex != null) { tex = CreateTexture(impTex, parser.GetNewID(typeof(odfTexture)), parser.TextureSection._FormatType, Path.GetDirectoryName(parser.ODFPath)); parser.TextureSection.AddChild(tex); texIDs[j] = tex.Id; } } else { texIDs[j] = tex.Id; } } } } odfSubmesh newSubmesh = newMesh[i]; newSubmesh.Id = parser.GetNewID(typeof(odfSubmesh)); newSubmesh.MaterialId = mat != null ? mat.Id : ObjectID.INVALID; newSubmesh.TextureIds = texIDs; List<odfVertex> newVertexList = newSubmesh.VertexList; if (worldCoords[i]) { for (int j = 0; j < newVertexList.Count; j++) { newVertexList[j].Position = Vector3.TransformCoordinate(newVertexList[j].Position, transform); } } odfSubmesh baseSubmesh = null; odfBoneList newBones = null; int newBonesIdx = -1; int idx = indices[i]; if ((frameMesh != null) && (idx >= 0) && (idx < frameMesh.Count)) { baseSubmesh = frameMesh[idx]; submeshIDtranslation.Add(newSubmesh.Id, baseSubmesh.Id); for (int j = 0; j < baseSubmesh.TextureIds.Length; j++) { ObjectID texID = baseSubmesh.TextureIds[j]; newSubmesh.TextureIds[j] = texID; } newSubmesh.Name = new ObjectName(baseSubmesh.Name.Name, baseSubmesh.Name.Info); CopyUnknowns(baseSubmesh, newSubmesh, parser.MeshSection._FormatType); if ((bonesMethod == CopyMeshMethod.CopyOrder) || (bonesMethod == CopyMeshMethod.CopyNear)) { odfBoneList baseBones = odf.FindBoneList(baseSubmesh.Id, parser.EnvelopeSection); if (baseBones != null) { newBones = baseBones.Clone(); newBones.Id = ObjectID.INVALID;// parser.GetNewID(typeof(odfBoneList)); newBones.SubmeshId = newSubmesh.Id; newBonesIdx = parser.EnvelopeSection.IndexOf(baseBones); } } else if (bonesMethod == CopyMeshMethod.Replace) { newBones = CreateBoneList(ObjectID.INVALID/*parser.GetNewID(typeof(odfBoneList))*/, frame.Id, newSubmesh, mesh.BoneList, transform, parser.FrameSection.RootFrame); newBonesIdx = parser.EnvelopeSection.Count; } } else { CreateUnknowns(newSubmesh, parser.MeshSection._FormatType); newBones = CreateBoneList(ObjectID.INVALID/*parser.GetNewID(typeof(odfBoneList))*/, frame.Id, newSubmesh, mesh.BoneList, transform, parser.FrameSection.RootFrame); newBonesIdx = parser.EnvelopeSection.Count; } if (newBones != null) { parser.EnvelopeSection.InsertChild(newBonesIdx, newBones); } if (baseSubmesh != null) { if (normalsMethod == CopyMeshMethod.CopyOrder) { odf.CopyNormalsOrder(baseSubmesh.VertexList, newSubmesh.VertexList); } else if (normalsMethod == CopyMeshMethod.CopyNear) { odf.CopyNormalsNear(baseSubmesh.VertexList, newSubmesh.VertexList); } if (bonesMethod == CopyMeshMethod.CopyOrder) { odf.CopyBonesOrder(baseSubmesh.VertexList, newSubmesh.VertexList, newBones); } else if (bonesMethod == CopyMeshMethod.CopyNear) { odf.CopyBonesNear(baseSubmesh.VertexList, newSubmesh.VertexList, newBones); } } if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i]) { replaceSubmeshes[idx] = newSubmesh; } else { addSubmeshes.Add(newSubmesh); } } if ((frameMesh != null) && merge) { newMesh.Clear(); newMesh.Capacity = replaceSubmeshes.Length + addSubmeshes.Count; for (int i = 0, submeshesRemoved = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] == null) { odfSubmesh newSubmesh = frameMesh[i - submeshesRemoved++]; frameMesh.RemoveChild(newSubmesh); // save the bone list from being deleted in RemoveMesh newMesh.AddChild(newSubmesh); } else { newMesh.AddChild(replaceSubmeshes[i]); } } newMesh.AddRange(addSubmeshes); } if (frameMesh != null) { RemoveMesh(parser, frameMesh, frame, false); parser.UsedIDs.Add((int)newMesh.Id, typeof(odfMesh)); frame.MeshId = newMesh.Id; List<ObjectID> removeKeyList = new List<ObjectID>(); foreach (odfSubmesh submesh in newMesh) { ObjectID newSubmeshID = submesh.Id; ObjectID baseSubmeshID; if (submeshIDtranslation.TryGetValue(newSubmeshID, out baseSubmeshID)) { if (odf.FindBoneList(baseSubmeshID, parser.EnvelopeSection) == null) { odfBoneList boneList = odf.FindBoneList(newSubmeshID, parser.EnvelopeSection); if (boneList != null) boneList.SubmeshId = baseSubmeshID; submesh.Id = baseSubmeshID; parser.UsedIDs.Remove((int)newSubmeshID); } foreach (KeyValuePair<ObjectID, ObjectID> pair in submeshIDtranslation) { if (pair.Value == baseSubmeshID) { removeKeyList.Add(pair.Key); } } foreach (ObjectID removeId in removeKeyList) { submeshIDtranslation.Remove(removeId); } removeKeyList.Clear(); } } } }
public static void RemoveMesh(odfParser parser, odfMesh mesh, odfFrame meshFrame, bool deleteMorphs) { while (mesh.Count > 0) { odfSubmesh submesh = mesh[0]; RemoveSubmesh(parser, submesh, deleteMorphs); } meshFrame.MeshId = ObjectID.INVALID; parser.MeshSection.RemoveChild(mesh); parser.UsedIDs.Remove((int)mesh.Id); }
public static odfFrame CreateFrame(ImportedFrame frame, odfParser parser) { odfFrame newFrame = new odfFrame(new ObjectName(frame.Name, null), null, frame.Count); newFrame.MeshId = ObjectID.INVALID; newFrame.Matrix = frame.Matrix; for (int i = 0; i < frame.Count; i++) { newFrame.AddChild(CreateFrame(frame[i], parser)); } return newFrame; }
private ImportedFrame ConvertFrames(odfFrame frame) { ImportedFrame iFrame = new ImportedFrame(); iFrame.InitChildren(frame.Count); iFrame.Name = frame.Name; iFrame.Matrix = frame.Matrix; FrameList.Add(iFrame); foreach (odfFrame child in frame) { ImportedFrame iChild = ConvertFrames(child); iFrame.AddChild(iChild); } return iFrame; }
void MergeFrame(odfFrame srcParent, odfFrame destParent) { for (int i = 0; i < destParent.Count; i++) { var dest = destParent[i]; for (int j = 0; j < srcParent.Count; j++) { var src = srcParent[j]; if (src.Name.ToString() == dest.Name.ToString()) { MergeFrame(src, dest); srcParent.RemoveChild(j); if (dest.MeshId != null && (int)dest.MeshId != 0) { odfMesh mesh = odf.FindMeshListSome(dest.MeshId, Parser.MeshSection); odf.RemoveMesh(Parser, mesh, dest, false); } destParent.RemoveChild(i); destParent.InsertChild(i, src); break; } } } if (srcParent.Name.ToString() == destParent.Name.ToString()) { while (destParent.Count > 0) { var dest = destParent[0]; destParent.RemoveChild(0); srcParent.AddChild(dest); } } else { while (srcParent.Count > 0) { var src = srcParent[0]; srcParent.RemoveChild(0); destParent.AddChild(src); } } }
void MergeFrame(odfFrame newFrame, int destParentIdx) { odfFrame srcParent = new odfFrame(new ObjectName("A new frame", null), ObjectID.INVALID, 1); srcParent.AddChild(newFrame); odfFrame destParent; if (destParentIdx < 0) { destParent = new odfFrame(new ObjectName("Another new frame", null), ObjectID.INVALID, 1); destParent.AddChild(Parser.FrameSection.RootFrame); } else { destParent = Frames[destParentIdx]; } MergeFrame(srcParent, destParent); if (destParentIdx < 0) { Parser.FrameSection.RootFrame = srcParent[0]; srcParent.RemoveChild(0); } Frames.Clear(); InitFrames(Parser.FrameSection.RootFrame); }
void InitFrames(odfFrame frame) { Frames.Add(frame); for (int i = 0; i < frame.Count; i++) { InitFrames(frame[i]); } }
void DeleteReferringBones(odfFrame frame) { for (int i = 0; i < Parser.EnvelopeSection.Count; i++) { odfBoneList boneList = Parser.EnvelopeSection[i]; for (int j = 0; j < boneList.Count; j++) { odfBone bone = boneList[j]; if (bone.FrameId == frame.Id) { if (RemoveBone(Parser.EnvelopeSection.IndexOf(boneList), j)) i--; break; } } } foreach (odfFrame child in frame) { DeleteReferringBones(child); } }
void DeleteMeshesInSubframes(odfFrame frame, bool deleteMorphs) { if ((int)frame.MeshId != 0) { odfMesh mesh = odf.FindMeshListSome(frame.MeshId, Parser.MeshSection); odf.RemoveMesh(Parser, mesh, frame, deleteMorphs); } for (int i = 0; i < frame.Count; i++) { odfFrame subframe = frame[i]; DeleteMeshesInSubframes(subframe, deleteMorphs); } }
void AddFrame(odfFrame newFrame, int destParentIdx) { if (destParentIdx < 0) { Parser.FrameSection.RootFrame = newFrame; newFrame.ParentId = ObjectID.INVALID; } else { Frames[destParentIdx].AddChild(newFrame); newFrame.ParentId = new ObjectID(((odfFrame)newFrame.Parent).Id); } Frames.Clear(); InitFrames(Parser.FrameSection.RootFrame); }
void ReplaceFrame(odfFrame newFrame, int destParentIdx, bool deleteMorphs) { if (destParentIdx < 0) { Parser.FrameSection.RootFrame = newFrame; } else { var destParent = Frames[destParentIdx]; bool found = false; for (int i = 0; i < destParent.Count; i++) { var dest = destParent[i]; if (dest.Name.ToString() == newFrame.Name.ToString()) { DeleteMeshesInSubframes(dest, deleteMorphs); destParent.RemoveChild(i); destParent.InsertChild(i, newFrame); found = true; break; } } if (!found) { destParent.AddChild(newFrame); } } Frames.Clear(); InitFrames(Parser.FrameSection.RootFrame); }