private static MqoObject ParseObject(string line, StreamReader reader) { MqoObject mqoObject = new MqoObject(); try { int nameStart = line.IndexOf('\"') + 1; int nameEnd = line.IndexOf('\"', nameStart); string name = line.Substring(nameStart, nameEnd - nameStart); mqoObject.fullname = name; if (name.Contains("[W]") || name.Contains("[w]")) { mqoObject.worldCoords = true; name = name.Replace("[W]", String.Empty); name = name.Replace("[w]", String.Empty); } int posStart; if ((posStart = name.LastIndexOf('[')) >= 0) { posStart++; int posEnd = name.LastIndexOf(']'); int baseIdx; if ((posEnd > posStart) && Int32.TryParse(name.Substring(posStart, posEnd - posStart), out baseIdx)) { mqoObject.baseIdx = baseIdx; name = name.Substring(0, posStart - 1); } } if ((mqoObject.baseIdx < 0) && ((posStart = name.LastIndexOf('-')) >= 0)) { posStart++; int baseIdx; if (Int32.TryParse(name.Substring(posStart, name.Length - posStart), out baseIdx)) { mqoObject.baseIdx = baseIdx; name = name.Substring(0, posStart - 1); } } mqoObject.name = name; ParseVertices(reader, mqoObject); ParseFaces(reader, mqoObject); } catch (Exception ex) { Report.ReportLog("Error parsing object " + mqoObject.fullname + ": " + ex.Message); mqoObject = null; } return(mqoObject); }
private static void ParseVertices(StreamReader reader, MqoObject mqoObject) { MqoVertex[] vertices = null; string line; while ((line = reader.ReadLine()) != null) { int countStart = line.IndexOf("visible"); if (countStart >= 0) { int visible = Int32.Parse(line.Substring(countStart + 7 + 1)); if (visible > 0) { mqoObject.visible = true; } continue; } countStart = line.IndexOf("vertex"); if (countStart >= 0) { countStart += 7; int countEnd = line.IndexOf(' ', countStart); int vertexCount = Int32.Parse(line.Substring(countStart, countEnd - countStart)); vertices = new MqoVertex[vertexCount]; for (int i = 0; i < vertexCount; i++) { MqoVertex vertex = new MqoVertex(); line = reader.ReadLine(); string[] sArray = line.Split(new char[] { '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries); float[] coords = new float[] { Utility.ParseFloat(sArray[0]), Utility.ParseFloat(sArray[1]), Utility.ParseFloat(sArray[2]) }; for (int j = 0; j < 3; j++) { coords[j] /= 10f; if (coords[j].Equals(Single.NaN)) { throw new Exception("vertex " + i + " has invalid coordinates in mesh object " + mqoObject.fullname); } } vertex.coords = new Vector3(coords[0], coords[1], coords[2]); vertices[i] = vertex; } break; } } mqoObject.vertices = vertices; }
private static void ParseFaces(StreamReader reader, MqoObject mqoObject) { List <MqoFace> faceList = null; string line; while ((line = reader.ReadLine()) != null) { int countStart = line.IndexOf("face"); if (countStart >= 0) { countStart += 5; int countEnd = line.IndexOf(' ', countStart); int faceCount = Int32.Parse(line.Substring(countStart, countEnd - countStart)); faceList = new List <MqoFace>(faceCount); for (int i = 0; i < faceCount; i++) { // get vertex indices & uv line = reader.ReadLine(); string[] sArray = line.Split(new char[] { '\t', ' ', '(', ')' }, StringSplitOptions.RemoveEmptyEntries); int numVertices = Int32.Parse(sArray[0]); if (numVertices > 3) { throw new Exception("Face " + i + " in mesh object " + mqoObject.fullname + " has more than 3 vertices. Triangulate the meshes"); } else if (numVertices < 3) { Report.ReportLog("Warning: Skipping face " + i + " in mesh object " + mqoObject.fullname + " because it has a less than 3 vertices"); } else { MqoFace face = new MqoFace(); faceList.Add(face); for (int j = 1; j < sArray.Length; j++) { if (sArray[j].ToUpper() == "V") { for (int k = 0; k < face.vertexIndices.Length; k++) { face.vertexIndices[k] = Int32.Parse(sArray[++j]); } } else if (sArray[j].ToUpper() == "M") { face.materialIndex = Int32.Parse(sArray[++j]); } else if (sArray[j].ToUpper() == "UV") { for (int k = 0; k < face.UVs.Length; k++) { face.UVs[k] = new float[2] { Utility.ParseFloat(sArray[++j]), Utility.ParseFloat(sArray[++j]) }; } } else if (sArray[j].ToUpper() == "COL") { for (int k = 0; k < face.vertexIndices.Length; k++) { j++; if (!(mqoObject.vertices[face.vertexIndices[k]] is MqoVertexWithColour)) { MqoVertexWithColour vertCol = new MqoVertexWithColour(); vertCol.coords = mqoObject.vertices[face.vertexIndices[k]].coords; uint abgr = uint.Parse(sArray[j]); int argb = (int)(abgr & 0xFF00FF00) | (int)((abgr & 0x00FF0000) >> 16) | (int)((abgr & 0x000000FF) << 16); vertCol.colour = new Color4(argb); mqoObject.vertices[face.vertexIndices[k]] = vertCol; } } } } } } break; } } mqoObject.faces = faceList.ToArray(); }
public Importer(string path) { try { List <string> mqoMaterials = new List <string>(); List <MqoObject> mqoObjects = new List <MqoObject>(); using (StreamReader reader = new StreamReader(path, Utility.EncodingShiftJIS)) { string line; while ((line = reader.ReadLine()) != null) { if (line.Contains("Object")) { MqoObject mqoObject = ParseObject(line, reader); if (mqoObject != null) { mqoObjects.Add(mqoObject); } } else if (line.Contains("Material")) { string[] sArray = line.Split(new string[] { "\t", " " }, StringSplitOptions.RemoveEmptyEntries); int numMaterials = Int32.Parse(sArray[1]); while ((numMaterials > 0) && (line = reader.ReadLine()).Contains("\"")) { int matNameStart = line.IndexOf('\"') + 1; int matNameEnd = line.IndexOf('\"', matNameStart); mqoMaterials.Add(line.Substring(matNameStart, matNameEnd - matNameStart)); numMaterials--; } } } } List <List <MqoObject> > groupedMeshes = new List <List <MqoObject> >(); for (int i = 0; i < mqoObjects.Count; i++) { bool found = false; for (int j = 0; j < groupedMeshes.Count; j++) { if (mqoObjects[i].name == groupedMeshes[j][0].name) { groupedMeshes[j].Add(mqoObjects[i]); found = true; break; } } if (!found) { List <MqoObject> group = new List <MqoObject>(); group.Add(mqoObjects[i]); groupedMeshes.Add(group); } } MeshList = new List <ImportedMesh>(groupedMeshes.Count); for (int i = 0; i < groupedMeshes.Count; i++) { ImportedMesh meshList = ImportMeshList(groupedMeshes[i], mqoMaterials); MeshList.Add(meshList); } } catch (Exception e) { Report.ReportLog("Error importing .mqo: " + e.Message); } }