private void Export(DirectoryInfo dir, xxFrame meshFrame) { try { xaMorphSection morphSection = xaParser.MorphSection; xaMorphIndexSet indexSet = xa.FindMorphIndexSet(clip.Name, morphSection); ushort[] meshIndices = indexSet.MeshIndices; ushort[] morphIndices = indexSet.MorphIndices; xxMesh meshList = meshFrame.Mesh; int meshObjIdx = xa.MorphMeshObjIdx(meshIndices, meshList); if (meshObjIdx < 0) { throw new Exception("no valid mesh object was found for the morph"); } xxSubmesh meshObjBase = meshList.SubmeshList[meshObjIdx]; colorVertex = new bool[meshObjBase.VertexList.Count]; for (int i = 0; i < meshIndices.Length; i++) { colorVertex[meshIndices[i]] = true; } string dest = Utility.GetDestFile(dir, meshFrame.Name + "-" + clip.Name + "-", ".morph.mqo"); List <xaMorphKeyframeRef> refList = clip.KeyframeRefList; morphNames = new List <string>(refList.Count); vertLists = new List <List <ImportedVertex> >(refList.Count); for (int i = 0; i < refList.Count; i++) { if (!morphNames.Contains(refList[i].Name)) { List <ImportedVertex> vertList = xx.ImportedVertexList(meshObjBase.VertexList, xx.IsSkinned(meshList)); vertLists.Add(vertList); xaMorphKeyframe keyframe = xa.FindMorphKeyFrame(refList[i].Name, morphSection); for (int j = 0; j < meshIndices.Length; j++) { ImportedVertex vert = vertList[meshIndices[j]]; vert.Position = keyframe.PositionList[morphIndices[j]]; } morphNames.Add(keyframe.Name); } } faceList = xx.ImportedFaceList(meshObjBase.FaceList); Export(dest, meshObjBase.MaterialIndex); foreach (xxTexture tex in usedTextures) { xx.ExportTexture(tex, dir.FullName + @"\" + Path.GetFileName(tex.Name)); } Report.ReportLog("Finished exporting morph to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting morph: " + ex.Message); } }
public static void WriteMeshObject(StreamWriter writer, List <ImportedVertex> vertexList, List <ImportedFace> faceList, int mqoMatIdx, bool[] colorVertex) { writer.WriteLine("\tvertex " + vertexList.Count + " {"); for (int i = 0; i < vertexList.Count; i++) { ImportedVertex vertex = vertexList[i]; Vector3 pos = vertex.Position * 10f; writer.WriteLine("\t\t" + pos.X.ToFloatString() + " " + pos.Y.ToFloatString() + " " + pos.Z.ToFloatString()); } writer.WriteLine("\t}"); writer.WriteLine("\tface " + faceList.Count + " {"); for (int i = 0; i < faceList.Count; i++) { ImportedFace face = faceList[i]; int[] vertIndices = new int[] { face.VertexIndices[0], face.VertexIndices[2], face.VertexIndices[1] }; float[] uv1 = vertexList[vertIndices[0]].UV; float[] uv2 = vertexList[vertIndices[1]].UV; float[] uv3 = vertexList[vertIndices[2]].UV; writer.Write("\t\t3 V(" + vertIndices[0] + " " + vertIndices[1] + " " + vertIndices[2] + ")"); if (mqoMatIdx >= 0) { writer.Write(" M(" + mqoMatIdx + ")"); } writer.Write(" UV(" + uv1[0].ToFloatString() + " " + uv1[1].ToFloatString() + " " + uv2[0].ToFloatString() + " " + uv2[1].ToFloatString() + " " + uv3[0].ToFloatString() + " " + uv3[1].ToFloatString() + ")"); if ((colorVertex != null) && (colorVertex[vertIndices[0]] || colorVertex[vertIndices[1]] || colorVertex[vertIndices[2]])) { string s = " COL("; for (int j = 0; j < vertIndices.Length; j++) { if (colorVertex[vertIndices[j]]) { s += 0xFFFF0000 + " "; } else { s += 0xFF000000 + " "; } } s = s.Substring(0, s.Length - 1) + ")"; writer.Write(s); } writer.WriteLine(); } writer.WriteLine("\t}"); }
public static List <ImportedVertex> ImportedVertexList(List <xxVertex> vertList, bool skinned) { List <ImportedVertex> importedList = new List <ImportedVertex>(vertList.Count); for (int i = 0; i < vertList.Count; i++) { ImportedVertex importedVert = new ImportedVertex(); importedList.Add(importedVert); importedVert.Position = vertList[i].Position; importedVert.Normal = vertList[i].Normal; importedVert.UV = vertList[i].UV; importedVert.BoneIndices = vertList[i].BoneIndices; importedVert.Weights = vertList[i].Weights4(skinned); } return(importedList); }
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); }
private static ImportedMesh ImportMeshList(List <MqoObject> mqoObjects, List <string> mqoMaterials) { ImportedMesh meshList = new ImportedMesh(); meshList.Name = mqoObjects[0].name; float scale = 1f; if (!mqoObjects[0].worldCoords) { int startPos = meshList.Name.IndexOf("(Scale="); if (startPos > 0) { int endPos = meshList.Name.IndexOf(')'); scale = 1f / Single.Parse(meshList.Name.Substring(startPos + 7, endPos - startPos - 7)); } } meshList.BoneList = new List <ImportedBone>(0); meshList.SubmeshList = new List <ImportedSubmesh>(mqoObjects.Count); int vertIdx = 0; foreach (MqoObject mqoObject in mqoObjects) { List <VertexMap>[] vertexMapList = new List <VertexMap> [mqoMaterials.Count + 1]; Dictionary <int, VertexMap>[] vertexMapDic = new Dictionary <int, VertexMap> [mqoMaterials.Count + 1]; List <VertexMap[]>[] faceMap = new List <VertexMap[]> [mqoMaterials.Count + 1]; foreach (MqoFace mqoFace in mqoObject.faces) { int mqoFaceMatIdxOffset = mqoFace.materialIndex + 1; if (vertexMapList[mqoFaceMatIdxOffset] == null) { vertexMapList[mqoFaceMatIdxOffset] = new List <VertexMap>(mqoObject.vertices.Length); vertexMapDic[mqoFaceMatIdxOffset] = new Dictionary <int, VertexMap>(); faceMap[mqoFaceMatIdxOffset] = new List <VertexMap[]>(mqoObject.faces.Length); } VertexMap[] faceMapArray = new VertexMap[mqoFace.vertexIndices.Length]; faceMap[mqoFaceMatIdxOffset].Add(faceMapArray); for (int i = 0; i < mqoFace.vertexIndices.Length; i++) { VertexMap vertMap; if (!vertexMapDic[mqoFaceMatIdxOffset].TryGetValue(mqoFace.vertexIndices[i], out vertMap)) { ImportedVertex vert; MqoVertex mqoVert = mqoObject.vertices[mqoFace.vertexIndices[i]]; if (mqoVert is MqoVertexWithColour) { vert = new ImportedVertexWithColour(); ((ImportedVertexWithColour)vert).Colour = ((MqoVertexWithColour)mqoVert).colour; } else { vert = new ImportedVertex(); } vert.BoneIndices = new byte[4]; vert.Weights = new float[4]; vert.Normal = new Vector3(); vert.UV = mqoFace.UVs[i]; vert.Position = mqoVert.coords * scale; vertMap = new VertexMap { mqoIdx = mqoFace.vertexIndices[i], vert = vert }; vertexMapDic[mqoFaceMatIdxOffset].Add(mqoFace.vertexIndices[i], vertMap); vertMap.uvDic.Add(mqoFace.UVs[i], vertMap); vertexMapList[mqoFaceMatIdxOffset].Add(vertMap); } VertexMap uvVertMap; if (!vertMap.uvDic.TryGetValue(mqoFace.UVs[i], out uvVertMap)) { ImportedVertex vert = new ImportedVertex(); vert.BoneIndices = new byte[4]; vert.Weights = new float[4]; vert.Normal = new Vector3(); vert.UV = mqoFace.UVs[i]; vert.Position = mqoObject.vertices[mqoFace.vertexIndices[i]].coords; uvVertMap = new VertexMap { mqoIdx = Int32.MaxValue, vert = vert }; vertMap.uvDic.Add(mqoFace.UVs[i], uvVertMap); vertexMapList[mqoFaceMatIdxOffset].Add(uvVertMap); } faceMapArray[i] = uvVertMap; } } for (int i = 0; i < vertexMapList.Length; i++) { if (vertexMapList[i] != null) { ImportedSubmesh mesh = new ImportedSubmesh(); mesh.VertexList = new List <ImportedVertex>(vertexMapList[i].Count); mesh.FaceList = new List <ImportedFace>(faceMap[i].Count); mesh.Index = mqoObject.baseIdx; mesh.WorldCoords = mqoObject.worldCoords; mesh.Visible = mqoObject.visible; int matIdx = i - 1; if ((matIdx >= 0) && (matIdx < mqoMaterials.Count)) { mesh.Material = mqoMaterials[matIdx]; } meshList.SubmeshList.Add(mesh); vertexMapList[i].Sort(); for (int j = 0; j < vertexMapList[i].Count; j++) { vertexMapList[i][j].wsMeshIdx = j; mesh.VertexList.Add(vertexMapList[i][j].vert); vertIdx++; } for (int j = 0; j < faceMap[i].Count; j++) { ImportedFace face = new ImportedFace(); face.VertexIndices = new int[] { faceMap[i][j][0].wsMeshIdx, faceMap[i][j][2].wsMeshIdx, faceMap[i][j][1].wsMeshIdx }; mesh.FaceList.Add(face); } } } } return(meshList); }