public void ConvertAnimation(odfANIMSection anim, odfParser odaParser, bool odaSkeleton) { if (odaSkeleton) { FrameList.Clear(); ConvertFrames(odaParser.FrameSection.RootFrame); } ImportedKeyframedAnimation iAnim = new ImportedKeyframedAnimation(); AnimationList.Add(iAnim); iAnim.TrackList = new List <ImportedAnimationKeyframedTrack>(anim.Count); string notFound = String.Empty; foreach (odfTrack track in anim) { odfFrame boneFrame = odf.FindFrame(track.BoneFrameId, odaParser.FrameSection.RootFrame); if (boneFrame == null) { notFound += (notFound.Length > 0 ? ", " : "") + track.BoneFrameId; continue; } ImportedAnimationKeyframedTrack iTrack = new ImportedAnimationKeyframedTrack(); iAnim.TrackList.Add(iTrack); iTrack.Name = boneFrame.Name; iTrack.Keyframes = ConvertTrack(track.KeyframeList); } if (notFound.Length > 0) { Report.ReportLog("Warning: Animations weren't converted for the following missing frame IDs: " + notFound); } }
public static void ReplaceMaterial(odfParser parser, ImportedMaterial material) { odfMaterial mat = CreateMaterial(material, null); bool found = false; for (int i = 0; i < parser.MaterialSection.Count; i++) { if (parser.MaterialSection[i].Name == material.Name) { odfMaterial original = parser.MaterialSection[i]; mat.Id = original.Id; CopyUnknown(original, mat); parser.MaterialSection.RemoveChild(i); parser.MaterialSection.InsertChild(i, mat); found = true; break; } } if (!found) { mat.Id = parser.GetNewID(typeof(odfMaterial)); CreateUnknown(mat); parser.MaterialSection.AddChild(mat); } }
public ODFConverter(odfParser parser, List <odfMesh> meshes) { FrameList = new List <ImportedFrame>(); ConvertFrames(parser.FrameSection.RootFrame); ConvertMeshes(meshes, parser); AnimationList = new List <ImportedAnimation>(); }
public static void Export(string dirPath, odfParser parser, odfMorphObject morphObj, bool skipUnusedProfiles) { DirectoryInfo dir = new DirectoryInfo(dirPath); ExporterMorph exporter = new ExporterMorph(dir, parser, morphObj, skipUnusedProfiles); exporter.Export(dir); }
public RenderObjectODF(odfParser parser, HashSet <int> meshIDs) { HighlightSubmesh = new SortedSet <int>(); highlightMaterial = new Material(); highlightMaterial.Ambient = new Color4(1, 1, 1, 1); highlightMaterial.Diffuse = new Color4(1, 0, 1, 0); this.device = Gui.Renderer.Device; Textures = new Texture[parser.TextureSection != null ? parser.TextureSection.Count : 0]; TextureDic = new Dictionary <int, int>(parser.TextureSection != null ? parser.TextureSection.Count : 0); Materials = new Material[parser.MaterialSection.Count]; BoneMatrixDic = new Dictionary <string, Matrix>(); rootFrame = CreateHierarchy(parser, meshIDs, device, out meshFrames); AnimationController = new AnimationController(numFrames, 30, 30, 1); Frame.RegisterNamedMatrices(rootFrame, AnimationController); for (int i = 0; i < meshFrames.Count; i++) { if (i == 0) { Bounds = meshFrames[i].Bounds; } else { Bounds = BoundingBox.Merge(Bounds, meshFrames[i].Bounds); } } }
public static void RemoveSubmesh(odfParser parser, odfSubmesh submesh, bool deleteMorphs) { odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection); if (boneList != null) { parser.EnvelopeSection.RemoveChild(boneList); parser.UsedIDs.Remove((int)boneList.Id); } if (parser.MorphSection != null && deleteMorphs) { for (int i = 0; i < parser.MorphSection.Count; i++) { odfMorphObject morphObj = parser.MorphSection[i]; if (morphObj.SubmeshId == submesh.Id) { parser.MorphSection.RemoveChild(i); --i; } } } ((odfMesh)submesh.Parent).RemoveChild(submesh); }
public static void ReplaceAnimation(WorkspaceAnimation wsAnimation, odfParser parser, int resampleCount, bool linear, ReplaceAnimationMethod replaceMethod, string clip, int insertPos, bool negateQuaternionFlips) { if (parser.AnimSection == null) { Report.ReportLog(Path.GetFileName(parser.ODFPath) + " doesn't have an animation section. Skipping this animation"); return; } if (!(wsAnimation.importedAnimation is ImportedKeyframedAnimation)) { Report.ReportLog("The animation has incompatible keyframes."); return; } Report.ReportLog("Replacing animation ..."); List <KeyValuePair <string, ImportedAnimationKeyframe[]> > newTrackList = FbxUtility.CopyKeyframedAnimation(wsAnimation, resampleCount, linear); List <odfTrack> animationNodeList = odf.FindClip(clip, parser).ChildList; ImportedKeyframedAnimation iAnim = new ImportedKeyframedAnimation(); iAnim.TrackList = new List <ImportedAnimationKeyframedTrack>(animationNodeList.Count); Dictionary <string, ImportedAnimationKeyframedTrack> animationNodeDic = null; if (replaceMethod != ReplaceAnimationMethod.Replace) { animationNodeDic = new Dictionary <string, ImportedAnimationKeyframedTrack>(); foreach (odfTrack animationNode in animationNodeList) { ImportedAnimationKeyframedTrack iTrack = new ImportedAnimationKeyframedTrack(); iTrack.Name = odf.FindFrame(animationNode.BoneFrameId, parser.FrameSection.RootFrame).Name; iTrack.Keyframes = Plugins.ODFConverter.ConvertTrack(animationNode.KeyframeList); animationNodeDic.Add(odf.FindFrame(animationNode.BoneFrameId, parser.FrameSection.RootFrame).Name, iTrack); iAnim.TrackList.Add(iTrack); } } foreach (var newTrack in newTrackList) { ImportedAnimationKeyframe[] keyframes = newTrack.Value; Quaternion q = keyframes[0].Rotation; keyframes[0].Rotation *= -1; /* if (keyframes[0].Rotation.Angle == 0 || q.Angle == 0) * { * Report.ReportLog("track " + newTrack.Key + " r=" + keyframes[0].Rotation.Angle + " q=" + q.Angle); * }*/ } FbxUtility.ReplaceAnimation(replaceMethod, insertPos, newTrackList, iAnim, animationNodeDic, negateQuaternionFlips); animationNodeList.Clear(); foreach (var newTrack in iAnim.TrackList) { ImportedAnimationKeyframe[] keyframes = ((ImportedAnimationKeyframedTrack)newTrack).Keyframes; odfTrack animationNode = new odfTrack(keyframes.Length); odf.CreateUnknowns(animationNode); animationNodeList.Add(animationNode); animationNode.KeyframeList = Plugins.ODFConverter.ConvertTrack(keyframes); animationNode.BoneFrameId = odf.FindFrame(newTrack.Name, parser.FrameSection.RootFrame).Id; } }
public static odfMaterialSection ParseMaterialList(BinaryReader reader) { odfParser parser = new odfParser(String.Empty); odfFileSection fileSec = new odfFileSection(odfSectionType.MAT, String.Empty); reader.BaseStream.Seek(4, SeekOrigin.Begin); fileSec.Size = reader.ReadInt32(); return(parser.loadMAT(reader, fileSec) ? parser.MaterialSection : null); }
public static odfFrameSection ParseFrame(BinaryReader reader) { odfParser parser = new odfParser(String.Empty); odfFileSection fileSec = new odfFileSection(odfSectionType.FRAM, String.Empty); reader.BaseStream.Seek(4, SeekOrigin.Begin); fileSec.Size = reader.ReadInt32(); return(parser.loadFRAM(reader, fileSec) ? parser.FrameSection : null); }
public static odfTextureSection ParseTextureList(BinaryReader reader) { odfParser parser = new odfParser(String.Empty); odfFileSection fileSec = new odfFileSection(odfSectionType.TEX, String.Empty); reader.BaseStream.Seek(4, SeekOrigin.Begin); fileSec.Size = reader.ReadInt32(); return(parser.loadTEX(reader, fileSec) ? parser.TextureSection : null); }
public static void ExportMorphMqo([DefaultVar] string dirPath, odfParser odfParser, string morphObjName, bool skipUnusedProfiles) { if (dirPath == null) { dirPath = Path.GetDirectoryName(odfParser.ODFPath) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(odfParser.ODFPath); } odfMorphObject morphObj = odf.FindMorphObject(morphObjName, odfParser.MorphSection); Mqo.ExporterMorph.Export(dirPath, odfParser, morphObj, skipUnusedProfiles); }
public static void ReplaceTexture(odfParser parser, ImportedTexture impTex) { odfTexture newTex = CreateTexture(impTex, null, parser.TextureSection._FormatType, Path.GetDirectoryName(parser.ODFPath)); if (odf.FindTextureInfo(impTex.Name, parser.TextureSection) == null) { newTex.Id = parser.GetNewID(typeof(odfTexture)); parser.TextureSection.AddChild(newTex); } }
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 void MergeMaterial(odfMaterial srcMat, odfParser srcParser) { odfMaterial newMat = srcMat.Clone(); bool found = false; for (int i = 0; i < Parser.MaterialSection.Count; i++) { odfMaterial oldMat = Parser.MaterialSection[i]; if (oldMat.Name == newMat.Name) { newMat.Id = oldMat.Id; Parser.MaterialSection.RemoveChild(i); Parser.MaterialSection.InsertChild(i, newMat); found = true; break; } } if (!found) { Parser.MaterialSection.AddChild(newMat); if (Parser.IsUsedID(newMat.Id)) { newMat.Id = Parser.GetNewID(typeof(odfMaterial)); Report.ReportLog("Warning! Material " + newMat.Name + " got a new ID : " + newMat.Id); } else { Parser.UsedIDs.Add((int)newMat.Id, typeof(odfMaterial)); } } if (Parser.MataSection != null && srcParser.MataSection != null) { odfMaterialList newMatList = odf.FindMaterialList(newMat.Id, srcParser.MataSection); if (newMatList != null) { odfMaterialList matList = odf.FindMaterialList(newMat.Id, Parser.MataSection); if (matList != null) { int originalIdx = Parser.MataSection.IndexOf(matList); Parser.MataSection.RemoveChild(originalIdx); Parser.MataSection.InsertChild(originalIdx, newMatList); } else { Parser.MataSection.AddChild(newMatList); } } } }
public void MergeFrame(odfFrame srcFrame, odfParser srcParser, int destParentIdx) { List <ObjectID> newMeshIDs = new List <ObjectID>(); odfFrame newFrame = srcFrame.Clone(true, newMeshIDs, true); List <odfMesh> newMeshes = new List <odfMesh>(newMeshIDs.Count); List <odfBoneList> newBoneLists = new List <odfBoneList>(srcParser.EnvelopeSection != null ? srcParser.EnvelopeSection.Count : 0); string boneWarning = String.Empty; foreach (ObjectID meshID in newMeshIDs) { odfMesh srcMesh = odf.FindMeshListSome(meshID, srcParser.MeshSection); odfMesh mesh = srcMesh.Clone(); newMeshes.Add(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(); newBoneLists.Add(copy); } else { boneWarning += (boneWarning != String.Empty ? ", " : "") + mesh.ToString(); break; } } } } } MergeFrame(newFrame, destParentIdx); foreach (odfMesh mesh in newMeshes) { Parser.MeshSection.AddChild(mesh); } if (Parser.EnvelopeSection != null) { foreach (odfBoneList boneList in newBoneLists) { Parser.EnvelopeSection.AddChild(boneList); } } Parser.CollectObjectIDs(); if (boneWarning != String.Empty) { Report.ReportLog("Warning! Bones of " + boneWarning + " dropped because the destination had no Envelope section."); } }
public void HighlightBone(odfParser parser, int meshIdx, int submeshIdx, int boneIdx) { const int boneObjSize = 16; odfSubmesh submesh = parser.MeshSection[meshIdx][submeshIdx]; odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection); string boneFrameName = null; if (boneIdx >= 0) { odfBone bone = boneList[boneIdx]; boneFrameName = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name; } AnimationMeshContainer mesh = (AnimationMeshContainer)meshFrames[0].MeshContainer; for (int i = 0; mesh != null; i++) { if (i == submeshIdx && (mesh.MeshData != null) && (mesh.MeshData.Mesh != null)) { List <odfVertex> vertexList = submesh.VertexList; float[][] vertexWeights = ConvertVertexWeights(vertexList, boneList); FillVertexBuffer(mesh.MeshData.Mesh, vertexList, vertexWeights, boneIdx); // break; } if (boneIdx >= 0) { for (int idx = 0; idx < mesh.BoneLines.Length / boneObjSize; idx++) { if (mesh.BoneNames[idx] == boneFrameName) { for (int j = 0; j < boneObjSize; j++) { mesh.BoneLines[idx * boneObjSize + j].Color = Color.Crimson.ToArgb(); } break; } } } else { for (int idx = 0; idx < mesh.BoneLines.Length / boneObjSize; idx++) { for (int j = 0; j < boneObjSize; j++) { mesh.BoneLines[idx * boneObjSize + j].Color = Color.CornflowerBlue.ToArgb(); } } } mesh = (AnimationMeshContainer)mesh.NextMeshContainer; } }
public void Dispose() { Frames.Clear(); if (Materials != null) { Materials.Clear(); } if (Textures != null) { Textures.Clear(); } Parser = null; }
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); }
public void ConvertAnimations(odfParser odaParser, bool odaSkeleton) { if (odaParser.AnimSection != null) { ConvertAnimation(odaParser.AnimSection, odaParser, odaSkeleton); } if (odaParser.BANMList != null) { foreach (odfANIMSection anim in odaParser.BANMList) { ConvertAnimation(anim, odaParser, odaSkeleton); } } }
public static odfANIMSection FindClip(string name, odfParser parser) { if (name == "ANIM" || name == String.Empty || parser.BANMList == null) { return(parser.AnimSection); } foreach (odfBANMSection anim in parser.BANMList) { if (anim.Name == name) { return(anim); } } return(null); }
private AnimationFrame CreateHierarchy(odfParser parser, HashSet <int> meshIDs, Device device, out List <AnimationFrame> meshFrames) { meshFrames = new List <AnimationFrame>(meshIDs.Count); HashSet <int> extractFrames = odf.SearchHierarchy(parser, meshIDs); #if !DONT_MIRROR Vector3 translate, scale; Quaternion rotate; parser.FrameSection.RootFrame.Matrix.Decompose(out scale, out rotate, out translate); parser.FrameSection.RootFrame.Matrix = Matrix.Scaling(scale.X, scale.Y, -scale.Z) * Matrix.RotationQuaternion(rotate) * Matrix.Translation(translate); #endif AnimationFrame rootFrame = CreateFrame(parser.FrameSection.RootFrame, parser, extractFrames, meshIDs, device, Matrix.Identity, meshFrames); SetupBoneMatrices(rootFrame, rootFrame); #if !DONT_MIRROR parser.FrameSection.RootFrame.Matrix = Matrix.Scaling(scale) * Matrix.RotationQuaternion(rotate) * Matrix.Translation(translate); #endif return(rootFrame); }
public static void ExportMqo([DefaultVar] odfParser parser, object[] meshNames, string dirPath, bool singleMqo, bool worldCoords) { List <odfMesh> meshes = new List <odfMesh>(meshNames.Length); foreach (string meshName in Utility.Convert <string>(meshNames)) { odfMesh mesh = odf.FindMeshListSome(meshName, parser.MeshSection); if (mesh != null || (mesh = odf.FindMeshListSome(new ObjectID(meshName), parser.MeshSection)) != null) { meshes.Add(mesh); } else { Report.ReportLog("Mesh " + meshName + " not found"); } } Mqo.Exporter.Export(dirPath, parser, meshes, singleMqo, worldCoords); }
public static HashSet <int> SearchHierarchy(odfParser parser, HashSet <int> meshIDs) { HashSet <int> exportFrames = new HashSet <int>(); SearchHierarchy(parser.FrameSection.RootFrame, parser.FrameSection.RootFrame, meshIDs, exportFrames); if (parser.EnvelopeSection != null) { for (int meshIdx = 0; meshIdx < parser.MeshSection.Count; meshIdx++) { odfMesh mesh = parser.MeshSection[meshIdx]; if (!meshIDs.Contains((int)mesh.Id)) { continue; } for (int meshObjIdx = 0; meshObjIdx < mesh.Count; meshObjIdx++) { odfSubmesh meshObj = mesh[meshObjIdx]; for (int envIdx = 0; envIdx < parser.EnvelopeSection.Count; envIdx++) { odfBoneList boneList = parser.EnvelopeSection[envIdx]; if (meshObj.Id != boneList.SubmeshId) { continue; } for (int i = 0; i < boneList.Count; i++) { ObjectID boneID = boneList[i].FrameId; if (!exportFrames.Contains((int)boneID)) { odfFrame boneParent = FindFrame(boneID, parser.FrameSection.RootFrame); while (boneParent != null && exportFrames.Add((int)boneParent.Id)) { boneParent = boneParent.Parent as odfFrame; } } } } } } } return(exportFrames); }
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 ReplaceFrame(odfFrame srcFrame, odfParser srcParser, int destParentIdx, bool deleteMorphs) { List <ObjectID> meshIDs = new List <ObjectID>(); odfFrame newFrame = srcFrame.Clone(true, meshIDs, true); ReplaceFrame(newFrame, destParentIdx, deleteMorphs); 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."); } }
public odfEditor(odfParser parser) { Parser = parser; Frames = new List <odfFrame>(); InitFrames(parser.FrameSection.RootFrame); if (parser.MaterialSection != null) { Materials = parser.MaterialSection.ChildList; } if (parser.TextureSection != null) { Textures = parser.TextureSection.ChildList; } if (parser.AnimSection != null) { Animations = new List <odfANIMSection>(1); Animations.Add(parser.AnimSection); if (parser.BANMList != null) { Animations.AddRange(parser.BANMList); } } }
public void MergeTexture(odfTexture tex, odfParser srcParser) { ImportedTexture impTex = new ImportedTexture(Path.GetDirectoryName(srcParser.ODFPath) + @"\" + tex.TextureFile); odfTexture newTex = odf.CreateTexture(impTex, null, Parser.TextureSection._FormatType, Path.GetDirectoryName(Parser.ODFPath)); newTex = tex.Clone(Parser.TextureSection._FormatType); bool found = false; for (int i = 0; i < Parser.TextureSection.Count; i++) { var oldTex = Parser.TextureSection[i]; if (oldTex.Name == newTex.Name) { newTex.Id = oldTex.Id; Parser.TextureSection.RemoveChild(i); Parser.TextureSection.InsertChild(i, newTex); found = true; break; } } if (!found) { Parser.TextureSection.AddChild(newTex); if (Parser.IsUsedID(newTex.Id)) { newTex.Id = Parser.GetNewID(typeof(odfTexture)); Report.ReportLog("Warning! Texture " + newTex.Name + " got a new ID : " + newTex.Id); } else { Parser.UsedIDs.Add((int)newTex.Id, typeof(odfTexture)); } } }
public static void MergeBoneLists(odfMesh mesh, Dictionary <ObjectID, ObjectID> submeshIDtrans, odfParser parser) { foreach (odfSubmesh submesh in mesh) { ObjectID baseSubmeshId = submeshIDtrans[submesh.Id]; for (int i = 0; i < parser.EnvelopeSection.Count; i++) { odfBoneList boneList = parser.EnvelopeSection[i]; if (boneList.SubmeshId == baseSubmeshId) { Dictionary <int, int> boneDic = new Dictionary <int, int>(boneList.Count); for (int j = 0; j < boneList.Count; j++) { odfBone bone = boneList[j]; boneDic.Add((int)bone.FrameId, j); } for (int j = i + 1; j < parser.EnvelopeSection.Count; j++) { odfBoneList boneList2 = parser.EnvelopeSection[j]; if (boneList2.SubmeshId == submesh.Id) { foreach (odfBone bone in boneList2) { int boneIdx; if (boneDic.TryGetValue((int)bone.FrameId, out boneIdx)) { boneList.RemoveChild(boneIdx); boneList.InsertChild(boneIdx, bone); } else { boneList.AddChild(bone); boneDic.Add((int)bone.FrameId, boneDic.Count); } } parser.EnvelopeSection.RemoveChild(boneList2); } } break; } else { Report.ReportLog("wrong"); } } } }
public static void WriteODF([DefaultVar] odfParser parser) { parser.WriteArchive(parser.ODFPath, true); }
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(); } } } }