public void ReplaceMesh(WorkspaceMesh mesh, int frameId, bool merge, string normals, string bones) { var normalsMethod = (CopyMeshMethod)Enum.Parse(typeof(CopyMeshMethod), normals); var bonesMethod = (CopyMeshMethod)Enum.Parse(typeof(CopyMeshMethod), bones); xx.ReplaceMesh(Frames[frameId], Parser, mesh, merge, normalsMethod, bonesMethod); Frames.Clear(); Meshes.Clear(); InitFrames(Parser.Frame); }
private void treeView_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) { DragSource source = (DragSource)e.Node.Tag; if (source.Type == typeof(WorkspaceMesh)) { var srcEditor = (ImportedEditor)Gui.Scripting.Variables[source.Variable]; ImportedMesh iMesh = srcEditor.Imported.MeshList[(int)source.Id]; WorkspaceMesh wsMesh = srcEditor.Meshes[(int)source.Id]; iMesh.Name = wsMesh.Name = e.Label; } }
public ImportedEditor(IImported imported) { Imported = imported; if (Imported.MaterialList != null && Imported.MaterialList.Count > 0) { Materials = new List <WorkspaceMaterial>(Imported.MaterialList.Count); foreach (ImportedMaterial mat in Imported.MaterialList) { WorkspaceMaterial wsMat = new WorkspaceMaterial(mat); Materials.Add(wsMat); } } if ((Imported.FrameList != null) && (Imported.FrameList.Count > 0)) { Frames = new List <ImportedFrame>(); foreach (var frame in Imported.FrameList) { InitFrames(frame); } } if (Imported.MeshList != null && Imported.MeshList.Count > 0) { Meshes = new List <WorkspaceMesh>(Imported.MeshList.Count); foreach (ImportedMesh mesh in Imported.MeshList) { WorkspaceMesh wsMesh = new WorkspaceMesh(mesh); Meshes.Add(wsMesh); } } if (Imported.MorphList != null && Imported.MorphList.Count > 0) { Morphs = new List <WorkspaceMorph>(Imported.MorphList.Count); foreach (ImportedMorph morph in Imported.MorphList) { WorkspaceMorph wsMorph = new WorkspaceMorph(morph); Morphs.Add(wsMorph); } } if (Imported.AnimationList != null && Imported.AnimationList.Count > 0) { Animations = new List <WorkspaceAnimation>(Imported.AnimationList.Count); foreach (ImportedAnimation animation in Imported.AnimationList) { WorkspaceAnimation wsAnimation = new WorkspaceAnimation(animation); Animations.Add(wsAnimation); } } }
public ImportedEditor(IImported imported) { Imported = imported; if ((Imported.FrameList != null) && (Imported.FrameList.Count > 0)) { Frames = new List<ImportedFrame>(); foreach (var frame in Imported.FrameList) { InitFrames(frame); } } if (Imported.MeshList != null && Imported.MeshList.Count > 0) { Meshes = new List<WorkspaceMesh>(Imported.MeshList.Count); foreach (ImportedMesh mesh in Imported.MeshList) { WorkspaceMesh wsMesh = new WorkspaceMesh(mesh); Meshes.Add(wsMesh); } } if (Imported.MorphList != null && Imported.MorphList.Count > 0) { Morphs = new List<WorkspaceMorph>(Imported.MorphList.Count); foreach (ImportedMorph morph in Imported.MorphList) { WorkspaceMorph wsMorph = new WorkspaceMorph(morph); Morphs.Add(wsMorph); } } if (Imported.AnimationList != null && Imported.AnimationList.Count > 0) { Animations = new List<WorkspaceAnimation>(Imported.AnimationList.Count); foreach (ImportedAnimation animation in Imported.AnimationList) { WorkspaceAnimation wsAnimation = new WorkspaceAnimation(animation); Animations.Add(wsAnimation); } } }
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 odfMesh CreateMesh(WorkspaceMesh mesh, int subMeshFormat, out string[] materialNames, out int[] indices, out bool[] worldCoords, out bool[] replaceSubmeshesOption) { int numUncheckedSubmeshes = 0; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { if (!mesh.isSubmeshEnabled(submesh)) numUncheckedSubmeshes++; } int numSubmeshes = mesh.SubmeshList.Count - numUncheckedSubmeshes; materialNames = new string[numSubmeshes]; indices = new int[numSubmeshes]; worldCoords = new bool[numSubmeshes]; replaceSubmeshesOption = new bool[numSubmeshes]; odfMesh newMesh = new odfMesh(new ObjectName(String.Empty, null), null, numSubmeshes); for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++) { while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx])) submeshIdx++; ImportedSubmesh submesh = mesh.SubmeshList[submeshIdx]; odfSubmesh newSubmesh = new odfSubmesh(new ObjectName(String.Empty, null), null, subMeshFormat); newMesh.AddChild(newSubmesh); newSubmesh.MaterialId = ObjectID.INVALID; materialNames[i] = submesh.Material; indices[i] = submesh.Index; worldCoords[i] = submesh.WorldCoords; replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(mesh.SubmeshList[submeshIdx]); List<ImportedVertex> vertexList = submesh.VertexList; List<odfVertex> newVertexList = new List<odfVertex>(vertexList.Count); for (int j = 0; j < vertexList.Count; j++) { ImportedVertex vert = vertexList[j]; odfVertex newVertex = new odfVertex(); newVertex.Normal = vert.Normal; newVertex.UV = new Vector2(vert.UV[0], vert.UV[1]); newVertex.Weights = (float[])vert.Weights.Clone(); newVertex.BoneIndices = (byte[])vert.BoneIndices.Clone(); newVertex.Position = vert.Position; newVertexList.Add(newVertex); } newSubmesh.VertexList = newVertexList; List<ImportedFace> faceList = submesh.FaceList; List<odfFace> newFaceList = new List<odfFace>(faceList.Count); for (int j = 0; j < faceList.Count; j++) { int[] vertexIndices = faceList[j].VertexIndices; odfFace newFace = new odfFace(); newFace.VertexIndices = new ushort[3] { (ushort)vertexIndices[0], (ushort)vertexIndices[1], (ushort)vertexIndices[2] }; newFaceList.Add(newFace); } newSubmesh.FaceList = newFaceList; } return newMesh; }
private void AddList <T>(List <T> list, string rootName, string editorVar) { if ((list != null) && (list.Count > 0)) { TreeNode root = new TreeNode(rootName); root.Checked = true; this.treeView.AddChild(root); for (int i = 0; i < list.Count; i++) { dynamic item = list[i]; TreeNode node = new TreeNode(item is WorkspaceAnimation ? ((WorkspaceAnimation)item).importedAnimation is ImportedKeyframedAnimation ? "Animation" + i : "Animation(Reduced Keys)" + i : item.Name); node.Checked = true; node.Tag = new DragSource(editorVar, typeof(T), i); this.treeView.AddChild(root, node); if (item is WorkspaceMesh) { WorkspaceMesh mesh = item; for (int j = 0; j < mesh.SubmeshList.Count; j++) { ImportedSubmesh submesh = mesh.SubmeshList[j]; TreeNode submeshNode = new TreeNode(); submeshNode.Checked = mesh.isSubmeshEnabled(submesh); submeshNode.Tag = submesh; submeshNode.ContextMenuStrip = this.contextMenuStripSubmesh; this.treeView.AddChild(node, submeshNode); UpdateSubmeshNode(submeshNode); } } else if (item is WorkspaceMorph) { WorkspaceMorph morph = item; string extraInfo = morph.MorphedVertexIndices != null ? " (morphed vertices: " + morph.MorphedVertexIndices.Count : String.Empty; extraInfo += (extraInfo.Length == 0 ? " (" : ", ") + "keyframes: " + morph.KeyframeList.Count + ")"; node.Text += extraInfo; for (int j = 0; j < morph.KeyframeList.Count; j++) { ImportedMorphKeyframe keyframe = morph.KeyframeList[j]; TreeNode keyframeNode = new TreeNode(); keyframeNode.Checked = morph.isMorphKeyframeEnabled(keyframe); keyframeNode.Tag = keyframe; keyframeNode.ContextMenuStrip = this.contextMenuStripMorphKeyframe; this.treeView.AddChild(node, keyframeNode); UpdateMorphKeyframeNode(keyframeNode); } } else if (item is WorkspaceAnimation) { WorkspaceAnimation animation = item; if (animation.importedAnimation is ImportedKeyframedAnimation) { List <ImportedAnimationKeyframedTrack> trackList = ((ImportedKeyframedAnimation)animation.importedAnimation).TrackList; for (int j = 0; j < trackList.Count; j++) { ImportedAnimationKeyframedTrack track = trackList[j]; TreeNode trackNode = new TreeNode(); trackNode.Checked = animation.isTrackEnabled(track); trackNode.Tag = track; int numKeyframes = 0; foreach (ImportedAnimationKeyframe keyframe in track.Keyframes) { if (keyframe != null) { numKeyframes++; } } trackNode.Text = "Track: " + track.Name + ", Keyframes: " + numKeyframes; this.treeView.AddChild(node, trackNode); } } else if (animation.importedAnimation is ImportedSampledAnimation) { List <ImportedAnimationSampledTrack> trackList = ((ImportedSampledAnimation)animation.importedAnimation).TrackList; for (int j = 0; j < trackList.Count; j++) { ImportedAnimationSampledTrack track = trackList[j]; TreeNode trackNode = new TreeNode(); trackNode.Checked = animation.isTrackEnabled(track); trackNode.Tag = track; int numScalings = 0; for (int k = 0; k < track.Scalings.Length; k++) { if (track.Scalings[k] != null) { numScalings++; } } int numRotations = 0; for (int k = 0; k < track.Rotations.Length; k++) { if (track.Rotations[k] != null) { numRotations++; } } int numTranslations = 0; for (int k = 0; k < track.Translations.Length; k++) { if (track.Translations[k] != null) { numTranslations++; } } trackNode.Text = "Track: " + track.Name + ", Length: " + track.Scalings.Length + ", Scalings: " + numScalings + ", Rotations: " + numRotations + ", Translations: " + numTranslations; this.treeView.AddChild(node, trackNode); } } } } } }
public static void ReplaceMesh(xxFrame frame, xxParser parser, WorkspaceMesh mesh, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod) { Matrix transform = Matrix.Identity; xxFrame transformFrame = frame; while (transformFrame != null) { transform = transformFrame.Matrix * transform; transformFrame = (xxFrame)transformFrame.Parent; } transform.Invert(); string[] materialNames; int[] indices; bool[] worldCoords; bool[] replaceSubmeshesOption; xxMesh xxMesh = CreateMesh(mesh, parser.Format, out materialNames, out indices, out worldCoords, out replaceSubmeshesOption); if (frame.Mesh == null) { CreateUnknowns(xxMesh); } else { CopyUnknowns(frame.Mesh, xxMesh); if ((bonesMethod == CopyMeshMethod.CopyOrder) || (bonesMethod == CopyMeshMethod.CopyNear)) { xxMesh.BoneList = new List<xxBone>(frame.Mesh.BoneList.Count); for (int i = 0; i < frame.Mesh.BoneList.Count; i++) { xxMesh.BoneList.Add(frame.Mesh.BoneList[i].Clone()); } } } xxSubmesh[] replaceSubmeshes = (frame.Mesh == null) ? null : new xxSubmesh[frame.Mesh.SubmeshList.Count]; List<xxSubmesh> addSubmeshes = new List<xxSubmesh>(xxMesh.SubmeshList.Count); for (int i = 0; i < xxMesh.SubmeshList.Count; i++) { for (int j = 0; j < parser.MaterialList.Count; j++) { if (parser.MaterialList[j].Name == materialNames[i]) { xxMesh.SubmeshList[i].MaterialIndex = j; break; } } xxSubmesh xxSubmesh = xxMesh.SubmeshList[i]; List<xxVertex> xxVertexList = xxSubmesh.VertexList; if (worldCoords[i]) { for (int j = 0; j < xxVertexList.Count; j++) { xxVertexList[j].Position = Vector3.TransformCoordinate(xxVertexList[j].Position, transform); } } xxSubmesh baseSubmesh = null; int idx = indices[i]; if ((frame.Mesh != null) && (idx >= 0) && (idx < frame.Mesh.SubmeshList.Count)) { baseSubmesh = frame.Mesh.SubmeshList[idx]; CopyUnknowns(baseSubmesh, xxSubmesh, parser.Format, xxMesh.NumVector2PerVertex); } else { CreateUnknowns(xxSubmesh, parser.Format, xxMesh.NumVector2PerVertex); } if (baseSubmesh != null) { if (normalsMethod == CopyMeshMethod.CopyOrder) { xx.CopyNormalsOrder(baseSubmesh.VertexList, xxSubmesh.VertexList); } else if (normalsMethod == CopyMeshMethod.CopyNear) { xx.CopyNormalsNear(baseSubmesh.VertexList, xxSubmesh.VertexList); } if (bonesMethod == CopyMeshMethod.CopyOrder) { xx.CopyBonesOrder(baseSubmesh.VertexList, xxSubmesh.VertexList); } else if (bonesMethod == CopyMeshMethod.CopyNear) { xx.CopyBonesNear(baseSubmesh.VertexList, xxSubmesh.VertexList); } } if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i]) { replaceSubmeshes[idx] = xxSubmesh; } else { addSubmeshes.Add(xxSubmesh); } } if ((frame.Mesh != null) && merge) { xxMesh.SubmeshList = new List<xxSubmesh>(replaceSubmeshes.Length + addSubmeshes.Count); List<xxSubmesh> copiedSubmeshes = new List<xxSubmesh>(replaceSubmeshes.Length); for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] == null) { xxSubmesh xxSubmesh = frame.Mesh.SubmeshList[i].Clone(); copiedSubmeshes.Add(xxSubmesh); xxMesh.SubmeshList.Add(xxSubmesh); } else { xxMesh.SubmeshList.Add(replaceSubmeshes[i]); } } xxMesh.SubmeshList.AddRange(addSubmeshes); if ((frame.Mesh.BoneList.Count == 0) && (xxMesh.BoneList.Count > 0)) { for (int i = 0; i < copiedSubmeshes.Count; i++) { List<xxVertex> vertexList = copiedSubmeshes[i].VertexList; for (int j = 0; j < vertexList.Count; j++) { vertexList[j].BoneIndices = new byte[4] { 0xFF, 0xFF, 0xFF, 0xFF }; } } } else if ((frame.Mesh.BoneList.Count > 0) && (xxMesh.BoneList.Count == 0)) { for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] != null) { List<xxVertex> vertexList = replaceSubmeshes[i].VertexList; for (int j = 0; j < vertexList.Count; j++) { vertexList[j].BoneIndices = new byte[4] { 0xFF, 0xFF, 0xFF, 0xFF }; } } } for (int i = 0; i < addSubmeshes.Count; i++) { List<xxVertex> vertexList = addSubmeshes[i].VertexList; for (int j = 0; j < vertexList.Count; j++) { vertexList[j].BoneIndices = new byte[4] { 0xFF, 0xFF, 0xFF, 0xFF }; } } } else if ((frame.Mesh.BoneList.Count > 0) && (xxMesh.BoneList.Count > 0)) { byte[] boneIdxMap; xxMesh.BoneList = MergeBoneList(frame.Mesh.BoneList, xxMesh.BoneList, out boneIdxMap); for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] != null) { List<xxVertex> vertexList = replaceSubmeshes[i].VertexList; for (int j = 0; j < vertexList.Count; j++) { byte[] boneIndices = vertexList[j].BoneIndices; vertexList[j].BoneIndices = new byte[4]; for (int k = 0; k < 4; k++) { vertexList[j].BoneIndices[k] = boneIndices[k] < 0xFF ? boneIdxMap[boneIndices[k]] : (byte)0xFF; } } } } for (int i = 0; i < addSubmeshes.Count; i++) { List<xxVertex> vertexList = addSubmeshes[i].VertexList; for (int j = 0; j < vertexList.Count; j++) { byte[] boneIndices = vertexList[j].BoneIndices; vertexList[j].BoneIndices = new byte[4]; for (int k = 0; k < 4; k++) { vertexList[j].BoneIndices[k] = boneIndices[k] < 0xFF ? boneIdxMap[boneIndices[k]] : (byte)0xFF; } } } } } if ((xxMesh.NumVector2PerVertex > 0) || ((frame.Mesh != null) && merge)) { xxMesh.VertexListDuplicate = CreateVertexListDup(xxMesh.SubmeshList); } frame.Mesh = xxMesh; SetBoundingBox(frame); }
public static void ReplaceMesh(remBone frame, remParser parser, WorkspaceMesh mesh, List<ImportedMaterial> materials, List<ImportedTexture> textures, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod, bool meshFrameCorrection) { remMesh frameREMMesh = rem.FindMesh(frame, parser.MESC); int startPos = 0; if (meshFrameCorrection) { // frame.matrix = Matrix.Scaling(-1f, 1f, 1f) * Matrix.RotationYawPitchRoll(0f, (float)(Math.PI / 2), (float)Math.PI); frame.matrix = Matrix.Identity; frame.matrix.M22 = frame.matrix.M33 = 0f; frame.matrix.M23 = frame.matrix.M32 = 1f; startPos = mesh.Name.IndexOf("(Scale"); if (startPos > 0) { int endPos = mesh.Name.IndexOf(')'); float scale; if (Single.TryParse(mesh.Name.Substring(startPos + 7, endPos - startPos - 7), out scale)) { frame.matrix *= Matrix.Scaling(new Vector3(scale)); } remId newFrameName = new remId(mesh.Name.Substring(0, startPos)); if (newFrameName != frame.name) { if (rem.FindFrame(newFrameName, parser.BONC.rootFrame) == null) { frame.name = newFrameName; } else { Report.ReportLog("Warning! Cant rename frame (and mesh) " + mesh.Name + " automatically to " + newFrameName + "."); } } } } Matrix transform = Matrix.Scaling(-1f, 1f, 1f); remBone transformFrame = frame; while (transformFrame != parser.BONC.rootFrame) { transform *= transformFrame.matrix; transformFrame = transformFrame.Parent as remBone; } transform.Invert(); string[] materialNames; int[] indices; bool[] worldCoords; bool[] replaceSubmeshesOption; remMesh newREMMesh = CreateMesh(mesh, out materialNames, out indices, out worldCoords, out replaceSubmeshesOption); if (startPos > 0) { newREMMesh.name = frame.name; } Mesh newMesh = new Mesh(newREMMesh, CreateBoneList(mesh, transform)); remSkin frameMeshSkin = null; Mesh frameMesh = null; if (frameREMMesh != null) { newMesh.name = frameREMMesh.name; frameMeshSkin = rem.FindSkin(frameREMMesh.name, parser.SKIC); frameMesh = new Mesh(frameREMMesh, frameMeshSkin); } Submesh[] replaceSubmeshes = frameMesh != null ? new Submesh[frameMesh.Count] : null; List<Submesh> addSubmeshes = new List<Submesh>(newMesh.Count); for (int i = 0; i < newMesh.Count; i++) { remMaterial mat = rem.FindMaterial(new remId(materialNames[i]), parser.MATC); if (materials != null) { if (mat == null) { mat = CreateMaterial(ImportedHelpers.FindMaterial(materialNames[i], materials)); parser.MATC.AddChild(mat); } /* if (textures != null) { string texName = materials[i].Textures[0]; remMaterial texMat = rem.FindMaterial(parser.MATC, new remId(texName)); if (texMat == null) { for (int k = 0; k < textures.Count; k++) { if (textures[k].Name == texName) { // texMat = CreateTexture(textures[k], Path.GetDirectoryName(parser.ODFPath)); break; } } } }*/ } Submesh newSubmesh = newMesh[i]; if (mat != null) { newSubmesh.MaterialName = mat.name; } if (worldCoords[i]) { List<remVertex> newVertexList = newSubmesh.VertexList; for (int j = 0; j < newVertexList.Count; j++) { newVertexList[j].Position = Vector3.TransformCoordinate(newVertexList[j].Position, transform); } } Submesh baseSubmesh = null; List<remBoneWeights> newBones = null; int idx = indices[i]; if ((frameMesh != null) && (idx >= 0) && (idx < frameMesh.Count)) { baseSubmesh = frameMesh[idx]; if ((bonesMethod == CopyMeshMethod.CopyOrder) || (bonesMethod == CopyMeshMethod.CopyNear)) { List<remBoneWeights> baseBones = baseSubmesh.BoneList; if (baseBones != null) { newBones = new List<remBoneWeights>(baseBones.Count); foreach (remBoneWeights boneWeights in baseBones) { remBoneWeights copy = boneWeights.Clone(); newBones.Add(copy); } newSubmesh.BoneList = newBones; } } else if (bonesMethod == CopyMeshMethod.Replace) newBones = newSubmesh.BoneList; } else { newBones = newSubmesh.BoneList; } if (baseSubmesh != null) { if (normalsMethod == CopyMeshMethod.CopyOrder) { rem.CopyNormalsOrder(baseSubmesh.VertexList, newSubmesh.VertexList); } else if (normalsMethod == CopyMeshMethod.CopyNear) { rem.CopyNormalsNear(baseSubmesh.VertexList, newSubmesh.VertexList); } if (bonesMethod == CopyMeshMethod.CopyOrder) { rem.CopyBonesOrder(baseSubmesh.VertexList, newSubmesh.VertexList, newBones); } else if (bonesMethod == CopyMeshMethod.CopyNear) { rem.CopyBonesNear(baseSubmesh.VertexList, newSubmesh.VertexList, newBones); } } if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i]) { replaceSubmeshes[idx] = newSubmesh; } else { addSubmeshes.Add(newSubmesh); } } if ((frameMesh != null) && merge) { newMesh.ChildList.Clear(); newMesh.ChildList.Capacity = replaceSubmeshes.Length + addSubmeshes.Count; for (int i = 0, submeshesRemoved = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] == null) { Submesh newSubmesh = frameMesh[i - submeshesRemoved++]; newMesh.AddChild(newSubmesh); } else { newMesh.AddChild(replaceSubmeshes[i]); } } newMesh.ChildList.AddRange(addSubmeshes); } remSkin skin; newREMMesh = newMesh.CreateMesh(out skin); newREMMesh.frame = frame.name; if (frameREMMesh != null) { CopyUnknowns(frameREMMesh, newREMMesh); parser.MESC.InsertChild(parser.MESC.IndexOf(frameREMMesh), newREMMesh); RemoveMesh(parser, frameREMMesh); } else { CreateUnknowns(newREMMesh); parser.MESC.AddChild(newREMMesh); } if (skin.Count > 0) { parser.SKIC.AddChild(skin); } }
public void ReplaceMesh(WorkspaceMesh mesh, List<ImportedMaterial> materials, List<ImportedTexture> textures, int frameIdx, bool merge, string normals, string bones, bool meshFrameCorrection) { var normalsMethod = (CopyMeshMethod)Enum.Parse(typeof(CopyMeshMethod), normals); var bonesMethod = (CopyMeshMethod)Enum.Parse(typeof(CopyMeshMethod), bones); rem.ReplaceMesh(Parser.BONC[frameIdx], Parser, mesh, materials, textures, merge, normalsMethod, bonesMethod, meshFrameCorrection); InitTextures(false, false); }
public static SkinnedMeshRenderer CreateSkinnedMeshRenderer(Animator parser, List<Material> materials, WorkspaceMesh mesh, Matrix meshMatrix, out int[] indices, out bool[] worldCoords, out bool[] replaceSubmeshesOption) { int numUncheckedSubmeshes = 0; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { if (!mesh.isSubmeshEnabled(submesh)) { numUncheckedSubmeshes++; } } int numSubmeshes = mesh.SubmeshList.Count - numUncheckedSubmeshes; indices = new int[numSubmeshes]; worldCoords = new bool[numSubmeshes]; replaceSubmeshesOption = new bool[numSubmeshes]; List<Matrix> poseMatrices = new List<Matrix>(mesh.BoneList.Count); Transform animatorTransform = parser.m_GameObject.instance.FindLinkedComponent(UnityClassID.Transform); List<PPtr<Transform>> bones = CreateBoneList(animatorTransform, meshMatrix, mesh.BoneList, poseMatrices); SkinnedMeshRenderer sMesh = new SkinnedMeshRenderer(parser.file); int totVerts = 0, totFaces = 0; sMesh.m_Materials.Capacity = numSubmeshes; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { if (!mesh.isSubmeshEnabled(submesh)) { continue; } Material matFound = materials.Find ( delegate(Material mat) { return mat.m_Name == submesh.Material; } ); sMesh.m_Materials.Add(new PPtr<Material>(matFound)); totVerts += submesh.VertexList.Count; totFaces += submesh.FaceList.Count; } Mesh uMesh = new Mesh(parser.file); uMesh.m_Name = mesh.Name; sMesh.m_Mesh = new PPtr<Mesh>(uMesh); sMesh.m_Bones = bones; uMesh.m_BindPose = poseMatrices; uMesh.m_BoneNameHashes = new List<uint>(poseMatrices.Count); for (int i = 0; i < mesh.BoneList.Count; i++) { string bone = mesh.BoneList[i].Name; uint hash = parser.m_Avatar.instance.BoneHash(bone); uMesh.m_BoneNameHashes.Add(hash); } uMesh.m_VertexData = new VertexData((uint)totVerts); uMesh.m_Skin = new List<BoneInfluence>(totVerts); uMesh.m_IndexBuffer = new byte[totFaces * 3 * sizeof(ushort)]; using (BinaryWriter vertWriter = new BinaryWriter(new MemoryStream(uMesh.m_VertexData.m_DataSize)), indexWriter = new BinaryWriter(new MemoryStream(uMesh.m_IndexBuffer))) { uMesh.m_LocalAABB.m_Center = new Vector3(Single.MaxValue, Single.MaxValue, Single.MaxValue); uMesh.m_LocalAABB.m_Extend = new Vector3(Single.MinValue, Single.MinValue, Single.MinValue); uMesh.m_SubMeshes = new List<SubMesh>(numSubmeshes); int vertIndex = 0; for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++) { while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx])) { submeshIdx++; } SubMesh submesh = new SubMesh(); submesh.indexCount = (uint)mesh.SubmeshList[submeshIdx].FaceList.Count * 3; submesh.vertexCount = (uint)mesh.SubmeshList[submeshIdx].VertexList.Count; submesh.firstVertex = (uint)vertIndex; uMesh.m_SubMeshes.Add(submesh); indices[i] = mesh.SubmeshList[submeshIdx].Index; worldCoords[i] = mesh.SubmeshList[submeshIdx].WorldCoords; replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(mesh.SubmeshList[submeshIdx]); List<ImportedVertex> vertexList = mesh.SubmeshList[submeshIdx].VertexList; Vector3 min = new Vector3(Single.MaxValue, Single.MaxValue, Single.MaxValue); Vector3 max = new Vector3(Single.MinValue, Single.MinValue, Single.MinValue); for (int str = 0; str < uMesh.m_VertexData.m_Streams.Count; str++) { StreamInfo sInfo = uMesh.m_VertexData.m_Streams[str]; if (sInfo.channelMask == 0) { continue; } for (int j = 0; j < vertexList.Count; j++) { ImportedVertex vert = vertexList[j]; for (int chn = 0; chn < uMesh.m_VertexData.m_Channels.Count; chn++) { ChannelInfo cInfo = uMesh.m_VertexData.m_Channels[chn]; if ((sInfo.channelMask & (1 << chn)) == 0) { continue; } vertWriter.BaseStream.Position = sInfo.offset + (j + submesh.firstVertex) * sInfo.stride + cInfo.offset; switch (chn) { case 0: Vector3 pos = vert.Position; pos.X *= -1; vertWriter.Write(pos); min = Vector3.Minimize(min, pos); max = Vector3.Maximize(max, pos); break; case 1: Vector3 normal = vert.Normal; normal.X *= -1; vertWriter.Write(normal); break; case 3: vertWriter.Write(vert.UV); break; case 5: Vector4 tangent = vert.Tangent; tangent.X *= -1; tangent.W *= -1; vertWriter.Write(tangent); break; } } if (sMesh.m_Bones.Count > 0 && sInfo.offset == 0 && uMesh.m_Skin.Count < totVerts) { BoneInfluence item = new BoneInfluence(); for (int k = 0; k < 4; k++) { item.boneIndex[k] = vert.BoneIndices[k] != 0xFF ? vert.BoneIndices[k] : 0; } vert.Weights.CopyTo(item.weight, 0); uMesh.m_Skin.Add(item); } } } vertIndex += (int)submesh.vertexCount; submesh.localAABB.m_Extend = max - min; submesh.localAABB.m_Center = min + submesh.localAABB.m_Extend / 2; uMesh.m_LocalAABB.m_Extend = Vector3.Maximize(uMesh.m_LocalAABB.m_Extend, max); uMesh.m_LocalAABB.m_Center = Vector3.Minimize(uMesh.m_LocalAABB.m_Center, min); List<ImportedFace> faceList = mesh.SubmeshList[submeshIdx].FaceList; submesh.firstByte = (uint)indexWriter.BaseStream.Position; for (int j = 0; j < faceList.Count; j++) { int[] vertexIndices = faceList[j].VertexIndices; indexWriter.Write((ushort)(vertexIndices[0] + submesh.firstVertex)); indexWriter.Write((ushort)(vertexIndices[2] + submesh.firstVertex)); indexWriter.Write((ushort)(vertexIndices[1] + submesh.firstVertex)); } } uMesh.m_LocalAABB.m_Extend -= uMesh.m_LocalAABB.m_Center; uMesh.m_LocalAABB.m_Center += uMesh.m_LocalAABB.m_Extend / 2; } return sMesh; }
public static void ReplaceMeshRenderer(Transform frame, Transform rootBone, Animator parser, List<Material> materials, WorkspaceMesh mesh, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod, bool targetFullMesh) { Matrix transform = Transform.WorldTransform(frame); int[] indices; bool[] worldCoords; bool[] replaceSubmeshesOption; SkinnedMeshRenderer sMesh = CreateSkinnedMeshRenderer(parser, materials, mesh, transform, out indices, out worldCoords, out replaceSubmeshesOption); vMesh destMesh = new Operations.vMesh(sMesh, true, false); SkinnedMeshRenderer sFrameMesh = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.SkinnedMeshRenderer); MeshRenderer frameMeshR = sFrameMesh; if (sFrameMesh == null) { frameMeshR = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.MeshRenderer); } Mesh frameMesh = frameMeshR != null ? Operations.GetMesh(frameMeshR) : null; vMesh srcMesh = null; List<vVertex> allVertices = null; if (frameMeshR == null || frameMesh == null) { sMesh.m_RootBone = new PPtr<Transform>(rootBone); if (rootBone != null) { sMesh.m_Mesh.instance.m_RootBoneNameHash = parser.m_Avatar.instance.BoneHash(rootBone.m_GameObject.instance.m_Name); } if (frameMeshR != null) { CopyUnknowns(frameMeshR, sMesh); } } else { if (sFrameMesh != null) { sMesh.m_RootBone = new PPtr<Transform>(sFrameMesh.m_RootBone.instance); sMesh.m_Mesh.instance.m_RootBoneNameHash = frameMesh.m_RootBoneNameHash; } else { sMesh.m_RootBone = new PPtr<Transform>((Component)null); } srcMesh = new Operations.vMesh(frameMeshR, true, false); CopyUnknowns(frameMeshR, sMesh); if (targetFullMesh && (normalsMethod == CopyMeshMethod.CopyNear || bonesMethod == CopyMeshMethod.CopyNear)) { allVertices = new List<vVertex>(); HashSet<Vector3> posSet = new HashSet<Vector3>(); foreach (vSubmesh submesh in srcMesh.submeshes) { allVertices.Capacity = allVertices.Count + submesh.vertexList.Count; foreach (vVertex vertex in submesh.vertexList) { if (!posSet.Contains(vertex.position)) { posSet.Add(vertex.position); allVertices.Add(vertex); } } } } } transform.Invert(); vSubmesh[] replaceSubmeshes = (srcMesh == null) ? null : new vSubmesh[srcMesh.submeshes.Count]; List<vSubmesh> addSubmeshes = new List<vSubmesh>(destMesh.submeshes.Count); for (int i = 0; i < destMesh.submeshes.Count; i++) { vSubmesh submesh = destMesh.submeshes[i]; List<vVertex> vVertexList = submesh.vertexList; if (worldCoords[i]) { for (int j = 0; j < vVertexList.Count; j++) { vVertexList[j].position = Vector3.TransformCoordinate(vVertexList[j].position, transform); } } vSubmesh baseSubmesh = null; int idx = indices[i]; if ((srcMesh != null) && (idx >= 0) && (idx < frameMesh.m_SubMeshes.Count)) { baseSubmesh = srcMesh.submeshes[idx]; CopyUnknowns(frameMesh.m_SubMeshes[idx], sMesh.m_Mesh.instance.m_SubMeshes[i]); } if (baseSubmesh != null) { if (normalsMethod == CopyMeshMethod.CopyOrder) { Operations.CopyNormalsOrder(baseSubmesh.vertexList, submesh.vertexList); } else if (normalsMethod == CopyMeshMethod.CopyNear) { Operations.CopyNormalsNear(targetFullMesh ? allVertices : baseSubmesh.vertexList, submesh.vertexList); } if (baseSubmesh.vertexList[0].weights != null) { if (bonesMethod == CopyMeshMethod.CopyOrder) { Operations.CopyBonesOrder(baseSubmesh.vertexList, submesh.vertexList); } else if (bonesMethod == CopyMeshMethod.CopyNear) { Operations.CopyBonesNear(targetFullMesh ? allVertices : baseSubmesh.vertexList, submesh.vertexList); } } } if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i]) { replaceSubmeshes[idx] = submesh; } else { addSubmeshes.Add(submesh); } } if ((srcMesh != null) && merge) { destMesh.submeshes = new List<vSubmesh>(replaceSubmeshes.Length + addSubmeshes.Count); List<vSubmesh> copiedSubmeshes = new List<vSubmesh>(replaceSubmeshes.Length); for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] == null) { vSubmesh srcSubmesh = srcMesh.submeshes[i]; copiedSubmeshes.Add(srcSubmesh); destMesh.submeshes.Add(srcSubmesh); } else { destMesh.submeshes.Add(replaceSubmeshes[i]); } } destMesh.submeshes.AddRange(addSubmeshes); if ((sFrameMesh == null || sFrameMesh.m_Bones.Count == 0) && (sMesh.m_Bones.Count > 0)) { for (int i = 0; i < copiedSubmeshes.Count; i++) { List<vVertex> vertexList = copiedSubmeshes[i].vertexList; for (int j = 0; j < vertexList.Count; j++) { vertexList[j].boneIndices = new int[4] { 0, 0, 0, 0 }; vertexList[j].weights = new float[4] { 0, 0, 0, 0 }; } } } else if (sFrameMesh != null && sFrameMesh.m_Bones.Count > 0) { int[] boneIdxMap; sMesh.m_Bones = MergeBoneList(sFrameMesh.m_Bones, sMesh.m_Bones, out boneIdxMap); uint[] boneHashes = new uint[sMesh.m_Bones.Count]; Matrix[] poseMatrices = new Matrix[sMesh.m_Bones.Count]; for (int i = 0; i < sFrameMesh.m_Bones.Count; i++) { boneHashes[i] = sFrameMesh.m_Mesh.instance.m_BoneNameHashes[i]; poseMatrices[i] = sFrameMesh.m_Mesh.instance.m_BindPose[i]; } for (int i = 0; i < boneIdxMap.Length; i++) { boneHashes[boneIdxMap[i]] = sMesh.m_Mesh.instance.m_BoneNameHashes[i]; poseMatrices[boneIdxMap[i]] = sMesh.m_Mesh.instance.m_BindPose[i]; } sMesh.m_Mesh.instance.m_BoneNameHashes.Clear(); sMesh.m_Mesh.instance.m_BoneNameHashes.AddRange(boneHashes); sMesh.m_Mesh.instance.m_BindPose.Clear(); sMesh.m_Mesh.instance.m_BindPose.AddRange(poseMatrices); if (bonesMethod == CopyMeshMethod.Replace) { for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] != null) { List<vVertex> vertexList = replaceSubmeshes[i].vertexList; if (vertexList[0].boneIndices != null) { for (int j = 0; j < vertexList.Count; j++) { int[] boneIndices = vertexList[j].boneIndices; vertexList[j].boneIndices = new int[4]; for (int k = 0; k < 4; k++) { vertexList[j].boneIndices[k] = boneIdxMap[boneIndices[k]]; } } } } } for (int i = 0; i < addSubmeshes.Count; i++) { List<vVertex> vertexList = addSubmeshes[i].vertexList; if (vertexList[0].boneIndices != null) { for (int j = 0; j < vertexList.Count; j++) { int[] boneIndices = vertexList[j].boneIndices; vertexList[j].boneIndices = new int[4]; for (int k = 0; k < 4; k++) { vertexList[j].boneIndices[k] = boneIdxMap[boneIndices[k]]; } } } } } } } destMesh.Flush(); if (frameMeshR != null) { frame.m_GameObject.instance.RemoveLinkedComponent(frameMeshR); //parser.file.RemoveSubfile(frameMeshR); if (frameMesh != null) { //parser.file.RemoveSubfile(frameMesh); parser.file.ReplaceSubfile(frameMesh, sMesh.m_Mesh.asset); } parser.file.ReplaceSubfile(frameMeshR, sMesh); } frame.m_GameObject.instance.AddLinkedComponent(sMesh); AssetBundle bundle = parser.file.Bundle; if (bundle != null) { if (frameMeshR != null) { if (frameMesh != null) { bundle.ReplaceComponent(frameMesh, sMesh.m_Mesh.asset); } bundle.ReplaceComponent(frameMeshR, sMesh); } else { bundle.RegisterForUpdate(parser.m_GameObject.asset); } } }
public void ReplaceMeshRenderer(WorkspaceMesh mesh, int frameId, int rootBoneId, bool merge, string normals, string bones, bool targetFullMesh) { var normalsMethod = (CopyMeshMethod)Enum.Parse(typeof(CopyMeshMethod), normals); var bonesMethod = (CopyMeshMethod)Enum.Parse(typeof(CopyMeshMethod), bones); Transform rootBone = rootBoneId >= 0 && rootBoneId < Frames.Count ? Frames[rootBoneId] : null; Operations.ReplaceMeshRenderer(Frames[frameId], rootBone, Parser, Materials, mesh, merge, normalsMethod, bonesMethod, targetFullMesh); InitLists(); Changed = true; }
private void AddList <T>(List <T> list, string rootName, string editorVar) { if ((list != null) && (list.Count > 0)) { TreeNode root = new TreeNode(rootName); root.Checked = true; this.treeView.AddChild(root); for (int i = 0; i < list.Count; i++) { dynamic item = list[i]; TreeNode node = new TreeNode(item is WorkspaceAnimation ? "Animation" + i : item.Name); node.Checked = true; node.Tag = new DragSource(editorVar, typeof(T), i); this.treeView.AddChild(root, node); if (item is WorkspaceMesh) { WorkspaceMesh mesh = item; for (int j = 0; j < mesh.SubmeshList.Count; j++) { ImportedSubmesh submesh = mesh.SubmeshList[j]; TreeNode submeshNode = new TreeNode(); submeshNode.Checked = mesh.isSubmeshEnabled(submesh); submeshNode.Tag = submesh; submeshNode.ContextMenuStrip = this.contextMenuStripSubmesh; this.treeView.AddChild(node, submeshNode); UpdateSubmeshNode(submeshNode); } } else if (item is WorkspaceMorph) { WorkspaceMorph morph = item; for (int j = 0; j < morph.KeyframeList.Count; j++) { ImportedMorphKeyframe keyframe = morph.KeyframeList[j]; TreeNode keyframeNode = new TreeNode(); keyframeNode.Checked = morph.isMorphKeyframeEnabled(keyframe); keyframeNode.Tag = keyframe; keyframeNode.ContextMenuStrip = this.contextMenuStripMorphKeyframe; this.treeView.AddChild(node, keyframeNode); UpdateMorphKeyframeNode(keyframeNode); } } else if (item is WorkspaceAnimation) { WorkspaceAnimation animation = item; for (int j = 0; j < animation.TrackList.Count; j++) { ImportedAnimationTrack track = animation.TrackList[j]; TreeNode trackNode = new TreeNode(); trackNode.Checked = animation.isTrackEnabled(track); trackNode.Tag = track; int numKeyframes = 0; foreach (ImportedAnimationKeyframe keyframe in track.Keyframes) { if (keyframe != null) { numKeyframes++; } } trackNode.Text = "Track: " + track.Name + ", Keyframes: " + numKeyframes; this.treeView.AddChild(node, trackNode); } } } } }
public static void ReplaceMesh(xxFrame frame, xxParser parser, WorkspaceMesh mesh, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod, bool targetFullMesh) { Matrix transform = Matrix.Identity; xxFrame transformFrame = frame; while (transformFrame != null) { transform = transformFrame.Matrix * transform; transformFrame = (xxFrame)transformFrame.Parent; } transform.Invert(); string[] materialNames; int[] indices; bool[] worldCoords; bool[] replaceSubmeshesOption; xxMesh xxMesh = CreateMesh(mesh, parser.Format, out materialNames, out indices, out worldCoords, out replaceSubmeshesOption); List <xxVertex> allVertices = null; if (frame.Mesh == null) { CreateUnknowns(xxMesh); } else { CopyUnknowns(frame.Mesh, xxMesh); if ((bonesMethod == CopyMeshMethod.CopyOrder) || (bonesMethod == CopyMeshMethod.CopyNear)) { xxMesh.BoneList = new List <xxBone>(frame.Mesh.BoneList.Count); for (int i = 0; i < frame.Mesh.BoneList.Count; i++) { xxMesh.BoneList.Add(frame.Mesh.BoneList[i].Clone()); } } if (targetFullMesh && (normalsMethod == CopyMeshMethod.CopyNear || bonesMethod == CopyMeshMethod.CopyNear)) { allVertices = new List <xxVertex>(); HashSet <Vector3> posSet = new HashSet <Vector3>(new VertexPositionComparer()); foreach (xxSubmesh submesh in frame.Mesh.SubmeshList) { allVertices.Capacity = allVertices.Count + submesh.VertexList.Count; foreach (xxVertex vertex in submesh.VertexList) { if (!posSet.Contains(vertex.Position)) { posSet.Add(vertex.Position); allVertices.Add(vertex); } } } } } xxSubmesh[] replaceSubmeshes = (frame.Mesh == null) ? null : new xxSubmesh[frame.Mesh.SubmeshList.Count]; List <xxSubmesh> addSubmeshes = new List <xxSubmesh>(xxMesh.SubmeshList.Count); for (int i = 0; i < xxMesh.SubmeshList.Count; i++) { for (int j = 0; j < parser.MaterialList.Count; j++) { if (parser.MaterialList[j].Name == materialNames[i]) { xxMesh.SubmeshList[i].MaterialIndex = j; break; } } xxSubmesh xxSubmesh = xxMesh.SubmeshList[i]; List <xxVertex> xxVertexList = xxSubmesh.VertexList; if (worldCoords[i]) { for (int j = 0; j < xxVertexList.Count; j++) { xxVertexList[j].Position = Vector3.TransformCoordinate(xxVertexList[j].Position, transform); } } xxSubmesh baseSubmesh = null; int idx = indices[i]; if ((frame.Mesh != null) && (idx >= 0) && (idx < frame.Mesh.SubmeshList.Count)) { baseSubmesh = frame.Mesh.SubmeshList[idx]; CopyUnknowns(baseSubmesh, xxSubmesh, parser.Format, xxMesh.NumVector2PerVertex); } else { CreateUnknowns(xxSubmesh, parser.Format, xxMesh.NumVector2PerVertex); } if (baseSubmesh != null) { if (normalsMethod == CopyMeshMethod.CopyOrder) { xx.CopyNormalsOrder(baseSubmesh.VertexList, xxSubmesh.VertexList); } else if (normalsMethod == CopyMeshMethod.CopyNear) { xx.CopyNormalsNear(targetFullMesh ? allVertices : baseSubmesh.VertexList, xxSubmesh.VertexList); } if (bonesMethod == CopyMeshMethod.CopyOrder) { xx.CopyBonesOrder(baseSubmesh.VertexList, xxSubmesh.VertexList); } else if (bonesMethod == CopyMeshMethod.CopyNear) { xx.CopyBonesNear(targetFullMesh ? allVertices : baseSubmesh.VertexList, xxSubmesh.VertexList); } } if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i]) { replaceSubmeshes[idx] = xxSubmesh; } else { addSubmeshes.Add(xxSubmesh); } } if ((frame.Mesh != null) && merge) { xxMesh.SubmeshList = new List <xxSubmesh>(replaceSubmeshes.Length + addSubmeshes.Count); List <xxSubmesh> copiedSubmeshes = new List <xxSubmesh>(replaceSubmeshes.Length); for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] == null) { xxSubmesh xxSubmesh = frame.Mesh.SubmeshList[i].Clone(); copiedSubmeshes.Add(xxSubmesh); xxMesh.SubmeshList.Add(xxSubmesh); } else { xxMesh.SubmeshList.Add(replaceSubmeshes[i]); } } xxMesh.SubmeshList.AddRange(addSubmeshes); if ((frame.Mesh.BoneList.Count == 0) && (xxMesh.BoneList.Count > 0)) { for (int i = 0; i < copiedSubmeshes.Count; i++) { List <xxVertex> vertexList = copiedSubmeshes[i].VertexList; for (int j = 0; j < vertexList.Count; j++) { vertexList[j].BoneIndices = new byte[4] { 0xFF, 0xFF, 0xFF, 0xFF }; } } } else if ((frame.Mesh.BoneList.Count > 0) && (xxMesh.BoneList.Count == 0)) { for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] != null) { List <xxVertex> vertexList = replaceSubmeshes[i].VertexList; for (int j = 0; j < vertexList.Count; j++) { vertexList[j].BoneIndices = new byte[4] { 0xFF, 0xFF, 0xFF, 0xFF }; } } } for (int i = 0; i < addSubmeshes.Count; i++) { List <xxVertex> vertexList = addSubmeshes[i].VertexList; for (int j = 0; j < vertexList.Count; j++) { vertexList[j].BoneIndices = new byte[4] { 0xFF, 0xFF, 0xFF, 0xFF }; } } } else if ((frame.Mesh.BoneList.Count > 0) && (xxMesh.BoneList.Count > 0)) { byte[] boneIdxMap; xxMesh.BoneList = MergeBoneList(frame.Mesh.BoneList, xxMesh.BoneList, out boneIdxMap); for (int i = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] != null) { List <xxVertex> vertexList = replaceSubmeshes[i].VertexList; for (int j = 0; j < vertexList.Count; j++) { byte[] boneIndices = vertexList[j].BoneIndices; vertexList[j].BoneIndices = new byte[4]; for (int k = 0; k < 4; k++) { vertexList[j].BoneIndices[k] = boneIndices[k] < 0xFF ? boneIdxMap[boneIndices[k]] : (byte)0xFF; } } } } for (int i = 0; i < addSubmeshes.Count; i++) { List <xxVertex> vertexList = addSubmeshes[i].VertexList; for (int j = 0; j < vertexList.Count; j++) { byte[] boneIndices = vertexList[j].BoneIndices; vertexList[j].BoneIndices = new byte[4]; for (int k = 0; k < 4; k++) { vertexList[j].BoneIndices[k] = boneIndices[k] < 0xFF ? boneIdxMap[boneIndices[k]] : (byte)0xFF; } } } } } if ((xxMesh.NumVector2PerVertex > 0) || ((frame.Mesh != null) && merge)) { xxMesh.VertexListDuplicate = CreateVertexListDup(xxMesh.SubmeshList); } frame.Mesh = xxMesh; SetBoundingBox(frame); }
public static xxMesh CreateMesh(WorkspaceMesh mesh, int xxFormat, out string[] materialNames, out int[] indices, out bool[] worldCoords, out bool[] replaceSubmeshesOption) { int numUncheckedSubmeshes = 0; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { if (!mesh.isSubmeshEnabled(submesh)) { numUncheckedSubmeshes++; } } int numSubmeshes = mesh.SubmeshList.Count - numUncheckedSubmeshes; materialNames = new string[numSubmeshes]; indices = new int[numSubmeshes]; worldCoords = new bool[numSubmeshes]; replaceSubmeshesOption = new bool[numSubmeshes]; xxMesh xxMesh = new xxMesh(); xxMesh.BoneList = CreateBoneList(mesh.BoneList); xxMesh.SubmeshList = new List <xxSubmesh>(mesh.SubmeshList.Count); for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++) { while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx])) { submeshIdx++; } xxSubmesh xxSubmesh = new xxSubmesh(); xxMesh.SubmeshList.Add(xxSubmesh); xxSubmesh.MaterialIndex = -1; materialNames[i] = mesh.SubmeshList[submeshIdx].Material; indices[i] = mesh.SubmeshList[submeshIdx].Index; worldCoords[i] = mesh.SubmeshList[submeshIdx].WorldCoords; replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(mesh.SubmeshList[submeshIdx]); List <ImportedVertex> vertexList = mesh.SubmeshList[submeshIdx].VertexList; List <xxVertex> xxVertexList = new List <xxVertex>(vertexList.Count); for (int j = 0; j < vertexList.Count; j++) { ImportedVertex vert = vertexList[j]; xxVertex xxVertex; if (xxFormat >= 4) { xxVertex = new xxVertexUShort(); CreateUnknown(xxVertex); } else { xxVertex = new xxVertexInt(); } xxVertex.Index = j; xxVertex.Normal = vert.Normal; xxVertex.UV = (float[])vert.UV.Clone(); xxVertex.Weights3 = new float[3] { vert.Weights[0], vert.Weights[1], vert.Weights[2] }; xxVertex.BoneIndices = (byte[])vert.BoneIndices.Clone(); xxVertex.Position = vert.Position; xxVertexList.Add(xxVertex); } xxSubmesh.VertexList = xxVertexList; List <ImportedFace> faceList = mesh.SubmeshList[submeshIdx].FaceList; List <xxFace> xxFaceList = new List <xxFace>(faceList.Count); for (int j = 0; j < faceList.Count; j++) { int[] vertexIndices = faceList[j].VertexIndices; xxFace xxFace = new xxFace(); xxFace.VertexIndices = new ushort[3] { (ushort)vertexIndices[0], (ushort)vertexIndices[1], (ushort)vertexIndices[2] }; xxFaceList.Add(xxFace); } xxSubmesh.FaceList = xxFaceList; } xxMesh.VertexListDuplicate = CreateVertexListDup(xxMesh.SubmeshList); return(xxMesh); }
public void ReplaceMesh(WorkspaceMesh mesh, List<ImportedMaterial> materials, List<ImportedTexture> textures, int frameIdx, bool merge, string normals, string bones) { var normalsMethod = (CopyMeshMethod)Enum.Parse(typeof(CopyMeshMethod), normals); var bonesMethod = (CopyMeshMethod)Enum.Parse(typeof(CopyMeshMethod), bones); odf.ReplaceMesh(Frames[frameIdx], Parser, mesh, materials, textures, merge, normalsMethod, bonesMethod); }
public static remMesh CreateMesh(WorkspaceMesh mesh, out string[] materialNames, out int[] indices, out bool[] worldCoords, out bool[] replaceSubmeshesOption) { int numUncheckedSubmeshes = 0; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { if (!mesh.isSubmeshEnabled(submesh)) numUncheckedSubmeshes++; } int numSubmeshes = mesh.SubmeshList.Count - numUncheckedSubmeshes; materialNames = new string[numSubmeshes]; indices = new int[numSubmeshes]; worldCoords = new bool[numSubmeshes]; replaceSubmeshesOption = new bool[numSubmeshes]; remMesh newMesh = new remMesh(numSubmeshes); newMesh.name = new remId(mesh.Name); List<remVertex> newVertices = new List<remVertex>(); List<int> newFaces = new List<int>(); List<int> newFaceMarks = new List<int>(); for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++) { while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx])) submeshIdx++; ImportedSubmesh submesh = mesh.SubmeshList[submeshIdx]; newMesh.AddMaterial(new remId(submesh.Material)); materialNames[i] = submesh.Material; indices[i] = submesh.Index; worldCoords[i] = submesh.WorldCoords; replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(submesh); List<ImportedFace> faceList = submesh.FaceList; newFaces.Capacity += faceList.Count * 3; int[] faceMarks = new int[faceList.Count]; for (int j = 0; j < faceList.Count; j++) { ImportedFace face = faceList[j]; for (int k = 0; k < 3; k++) { newFaces.Add(face.VertexIndices[k] + newVertices.Count); } faceMarks[j] = i; } newFaceMarks.AddRange(faceMarks); List<ImportedVertex> vertexList = submesh.VertexList; newVertices.Capacity += vertexList.Count; for (int j = 0; j < vertexList.Count; j++) { ImportedVertex vert = vertexList[j]; remVertex newVertex = new remVertex(); if (submesh.WorldCoords) { newVertex.Position = vert.Position; newVertex.Normal = vert.Normal; } else { newVertex.Position = new Vector3(vert.Position.X, -vert.Position.Z, vert.Position.Y); newVertex.Normal = new Vector3(vert.Normal.X, -vert.Normal.Z, vert.Normal.Y); } newVertex.UV = new Vector2(vert.UV[0], vert.UV[1]); newVertices.Add(newVertex); } } newMesh.vertices = newVertices.ToArray(); newMesh.faces = newFaces.ToArray(); newMesh.faceMarks = newFaceMarks.ToArray(); return newMesh; }
public static xxMesh CreateMesh(WorkspaceMesh mesh, int xxFormat, out string[] materialNames, out int[] indices, out bool[] worldCoords, out bool[] replaceSubmeshesOption) { int numUncheckedSubmeshes = 0; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { if (!mesh.isSubmeshEnabled(submesh)) numUncheckedSubmeshes++; } int numSubmeshes = mesh.SubmeshList.Count - numUncheckedSubmeshes; materialNames = new string[numSubmeshes]; indices = new int[numSubmeshes]; worldCoords = new bool[numSubmeshes]; replaceSubmeshesOption = new bool[numSubmeshes]; xxMesh xxMesh = new xxMesh(); xxMesh.BoneList = CreateBoneList(mesh.BoneList); xxMesh.SubmeshList = new List<xxSubmesh>(mesh.SubmeshList.Count); for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++) { while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx])) submeshIdx++; xxSubmesh xxSubmesh = new xxSubmesh(); xxMesh.SubmeshList.Add(xxSubmesh); xxSubmesh.MaterialIndex = -1; materialNames[i] = mesh.SubmeshList[submeshIdx].Material; indices[i] = mesh.SubmeshList[submeshIdx].Index; worldCoords[i] = mesh.SubmeshList[submeshIdx].WorldCoords; replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(mesh.SubmeshList[submeshIdx]); List<ImportedVertex> vertexList = mesh.SubmeshList[submeshIdx].VertexList; List<xxVertex> xxVertexList = new List<xxVertex>(vertexList.Count); for (int j = 0; j < vertexList.Count; j++) { ImportedVertex vert = vertexList[j]; xxVertex xxVertex; if (xxFormat >= 4) { xxVertex = new xxVertexUShort(); CreateUnknown(xxVertex); } else { xxVertex = new xxVertexInt(); } xxVertex.Index = j; xxVertex.Normal = vert.Normal; xxVertex.UV = (float[])vert.UV.Clone(); xxVertex.Weights3 = new float[3] { vert.Weights[0], vert.Weights[1], vert.Weights[2] }; xxVertex.BoneIndices = (byte[])vert.BoneIndices.Clone(); xxVertex.Position = vert.Position; xxVertexList.Add(xxVertex); } xxSubmesh.VertexList = xxVertexList; List<ImportedFace> faceList = mesh.SubmeshList[submeshIdx].FaceList; List<xxFace> xxFaceList = new List<xxFace>(faceList.Count); for (int j = 0; j < faceList.Count; j++) { int[] vertexIndices = faceList[j].VertexIndices; xxFace xxFace = new xxFace(); xxFace.VertexIndices = new ushort[3] { (ushort)vertexIndices[0], (ushort)vertexIndices[1], (ushort)vertexIndices[2] }; xxFaceList.Add(xxFace); } xxSubmesh.FaceList = xxFaceList; } xxMesh.VertexListDuplicate = CreateVertexListDup(xxMesh.SubmeshList); return xxMesh; }