public ConsoleAppShould() { _sw = new StringWriter(); Console.SetOut(_sw); LineInformation lineInfoVictoria = new LineInformation(); LineInformation lineInfoBakerloo = new LineInformation(); LineInformation lineInfoCircle = new LineInformation(); lineInfoVictoria.LineName = "Victoria"; lineInfoVictoria.LineStatus = "Good Service"; lineInfoBakerloo.LineName = "Bakerloo"; lineInfoBakerloo.LineStatus = "Good Service"; lineInfoCircle.LineName = "Circle"; lineInfoCircle.LineStatus = "Good Service"; _mockDataOfApi = new List <LineInformation> { lineInfoVictoria, lineInfoBakerloo, lineInfoCircle }; _mockOfApi = new Mock <ITFLAPIClient>(); }
// --- visual-basic-compatible number parsing (int32) --- private static int GetInt32FromArgument(int argumentIndex, string argumentName, int defaultValue, LineInformation lineInfo) { int value; if (TryGetInt32FromArgument(argumentIndex, argumentName, int.MinValue, int.MaxValue, defaultValue, true, lineInfo, out value)) { return value; } else { return defaultValue; } }
// --- validation functions --- private static void CheckMeshBuilderPresence(string command, LineInformation lineInfo, ref bool meshBuilderPresent) { if (!meshBuilderPresent) { string meshBuilder = lineInfo.FileInfo.IsB3d ? "[MeshBuilder]" : "CreateMeshBuilder"; string text = meshBuilder + " is required before " + command + " can be used on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); meshBuilderPresent = true; } }
/// <summary> /// Add entry to Lines Locations list /// </summary> /// <param name="iLine">Line Number</param> /// <param name="iAddress">Address related to that line</param> public void AddEntry(int iLine, int iAddress) { if (linesHash.ContainsKey(iLine)) { throw new PanicException(); } LineInformation newLine = new LineInformation(iLine, iAddress, -1); linesHash[iLine] = newLine; // Assuming the inserted line is a line with the largest index iMaxLine = iLine; }
private static bool CheckCommand(string actual, string b3dCommand, string csvCommand, LineInformation lineInfo) { if (lineInfo.FileInfo.IsB3d) { if (!string.Equals(actual, b3dCommand, StringComparison.OrdinalIgnoreCase)) { string text = actual + " should be " + b3dCommand + " in B3D files on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); return false; } } else { if (!string.Equals(actual, csvCommand, StringComparison.OrdinalIgnoreCase)) { string text = actual + " should be " + csvCommand + " in CSV files on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); return false; } } return true; }
private static bool CheckArgumentCount(string command, int actual, int lower, int upper, LineInformation lineInfo) { if (actual < lower | actual > upper) { if (lower == upper) { string text = command + " expects " + lower.ToString() + (lower == 1 ? " argument" : " arguments") + " but " + actual.ToString() + (actual == 1 ? " argument was" : " arguments were") + " found on line " + (lineInfo.LineNumber).ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); } else if (lower == 0) { string text = command + " expects at most " + upper.ToString() + (upper == 1 ? " argument" : " arguments") + " but " + actual.ToString() + (actual == 1 ? " argument was" : " arguments were") + " found on line " + (lineInfo.LineNumber).ToString() + " in \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); } else if (upper == int.MaxValue) { string text = command + " expects at least " + lower.ToString() + (lower == 1 ? " argument" : " arguments") + " but " + actual.ToString() + (actual == 1 ? " argument was" : " arguments were") + " found on line " + (lineInfo.LineNumber).ToString() + " in \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); } else { string text = command + " expects between " + lower.ToString() + " and " + upper.ToString() + " arguments but " + actual.ToString() + (actual == 1 ? " argument was" : " arguments were") + " found on line " + (lineInfo.LineNumber).ToString() + " in \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); } return false; } else { return true; } }
private static bool TryGetInt32FromArgument(int argumentIndex, string argumentName, int minValue, int maxValue, int defaultValue, bool allowMissingArgument, LineInformation lineInfo, out int value) { if (argumentIndex >= 0 && argumentIndex < lineInfo.ArgumentCount && lineInfo.Arguments[argumentIndex].Length != 0) { int success = TryParseInt32Vb(lineInfo.Arguments[argumentIndex], out value); if (success == 0) { string text = "\"" + lineInfo.Arguments[argumentIndex] + "\" as argument " + (argumentIndex + 1).ToString() + " (" + argumentName + ") to command " + lineInfo.Command + " is not a valid integer on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); value = defaultValue; return false; } if (lineInfo.FileInfo.StrictParsing & success == -1) { string text = "\"" + lineInfo.Arguments[argumentIndex] + "\" as argument " + (argumentIndex + 1).ToString() + " (" + argumentName + ") to command " + lineInfo.Command + " is a malformed integer and will be treated as " + value.ToString() + " on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); } if (value < minValue | value > maxValue) { if (minValue == int.MinValue) { value = maxValue; string text = "\"" + lineInfo.Arguments[argumentIndex] + "\" as argument " + (argumentIndex + 1).ToString() + " (" + argumentName + ") to command " + lineInfo.Command + " must be at most " + maxValue.ToString() + " on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); } else if (maxValue == int.MaxValue) { value = minValue; string text = "\"" + lineInfo.Arguments[argumentIndex] + "\" as argument " + (argumentIndex + 1).ToString() + " (" + argumentName + ") to command " + lineInfo.Command + " must be at least " + minValue.ToString() + " on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); } else { value = value < minValue ? minValue : maxValue; string text = "\"" + lineInfo.Arguments[argumentIndex] + "\" as argument " + (argumentIndex + 1).ToString() + " (" + argumentName + ") to command " + lineInfo.Command + " must be between " + minValue.ToString() + " and " + maxValue.ToString() + " on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); } return false; } return true; } else if (allowMissingArgument) { value = defaultValue; return true; } else { string text = "Argument " + (argumentIndex + 1).ToString() + " (" + argumentName + ") to command " + lineInfo.Command + " is missing on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; lineInfo.FileInfo.Logger.Add(text); value = defaultValue; return false; } }
public SourceInformation Source(TreeNode node) { SortedDictionary <int, float> metricOnLine; var sourceLocation = this.GetSourceLocation(node.BackingNode, node.BackingNode.Name, out metricOnLine); if (sourceLocation != null) { var sourceFile = sourceLocation.SourceFile; FieldInfo fi = typeof(SourceFile).GetField("m_symbolModule", BindingFlags.NonPublic | BindingFlags.Instance); if (fi != null) { PropertyInfo pi = typeof(SymbolModule).GetProperty("PdbForSourceServer", BindingFlags.NonPublic | BindingFlags.Instance); if (pi != null) { MethodInfo mi = typeof(SymbolModule).GetMethod("GetSrcSrvStream", BindingFlags.NonPublic | BindingFlags.Instance); if (mi != null) { string srcStream = mi.Invoke(pi.GetValue(fi.GetValue(sourceFile)), null) as string; if (srcStream != null) { string[] lines = srcStream.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); foreach (var line in lines) { // TFS DevDiv support if (line.StartsWith(sourceFile.BuildTimeFilePath)) { var split = line.Split('*'); var sourceInfo = new SourceInformation { Url = "http://vstfdevdiv:8080/DevDiv2/DevDiv/_versionControl/changeset/" + split[3].Trim() + "#path=" + split[2].Trim() + "&_a=contents", Type = "Url", Summary = metricOnLine.Select(m => new LineInformation { Metric = m.Value, LineNumber = m.Key + 1, Line = string.Empty }).ToList() }; return(sourceInfo); } } // support for source depot? return(null); } } } } // Source Database Format { var sdbFiles = Directory.GetFiles(this.reader.SourcePath, "*.sdb", SearchOption.AllDirectories); SourceInformation sourceInfo = null; foreach (var sdbFile in sdbFiles) { using (ZipArchive archive = ZipFile.OpenRead(sdbFile)) { foreach (ZipArchiveEntry entry in archive.Entries) { if (sourceFile.BuildTimeFilePath.EndsWith(entry.FullName, StringComparison.OrdinalIgnoreCase)) { int i = 0; var summaryLineMetrics = new List <LineInformation>(); var linemetrics = new List <LineInformation>(); sourceInfo = new SourceInformation(); sourceInfo.Lines = linemetrics; sourceInfo.Summary = summaryLineMetrics; sourceInfo.Type = "Lines"; using (var sr = new StreamReader(entry.Open())) { string line; while ((line = sr.ReadLine()) != null) { i++; float value = 0; if (metricOnLine.TryGetValue(i, out value)) { var lineInfo = new LineInformation { LineNumber = i, Metric = value, Line = line }; summaryLineMetrics.Add(lineInfo); linemetrics.Add(lineInfo); } else { linemetrics.Add(new LineInformation { LineNumber = i, Metric = value, Line = line }); } } } break; } } } } return(sourceInfo); } } return(null); }
// --- visual-basic-compatible number parsing (double) --- private static double GetDoubleFromArgument(int argumentIndex, string argumentName, double defaultValue, LineInformation lineInfo) { double value; if (TryGetDoubleFromArgument(argumentIndex, argumentName, double.MinValue, double.MaxValue, defaultValue, true, lineInfo, out value)) { return value; } else { return defaultValue; } }
public override Mesh Load(string file, MeshDecodingOptions options) { const bool strictParsing = true; // --- preparations --- bool isB3d = file.EndsWith(".b3d", StringComparison.OrdinalIgnoreCase); char commandArgumentSeparator = isB3d ? ' ' : ','; FileInformation fileInfo = new FileInformation(isB3d, file, strictParsing, options.Logger); List<MeshBuilder> meshBuilders = new List<MeshBuilder>(); MeshBuilder currentMeshBuilder = new MeshBuilder(); bool meshBuilderPresent = false; // --- line by line --- string[] lines = File.ReadAllLines(file, Encoding.UTF8); for (int l = 0; l < lines.Length; l++) { string line = lines[l]; // --- trim comments and whitespace --- int semicolon = line.IndexOf(';'); if (semicolon >= 0) { line = line.Substring(0, semicolon).Trim(); } else { line = line.Trim(); } if (line.Length != 0) { // --- split into command and argument sequence --- string command; string argumentSequence; int separator = line.IndexOf(commandArgumentSeparator); if (separator >= 0) { command = line.Substring(0, separator).TrimEnd(); argumentSequence = line.Substring(separator + 1).TrimStart(); } else { command = line; argumentSequence = string.Empty; } // --- handle malformed commands --- if (command.Length != 0) { if (isB3d) { int comma = command.IndexOf(','); if (comma >= 0) { argumentSequence = command.Substring(comma + 1).TrimStart() + ',' + argumentSequence; command = command.Substring(0, comma).TrimEnd(); if (strictParsing) { string text = "Command \"" + command + "\" must be separated from its arguments by a space in B3D files on line " + (l + 1).ToString() + " in file \"" + file + "\"."; options.Logger.Add(text); } } } else { int space = command.IndexOf(' '); if (space >= 0) { argumentSequence = command.Substring(space + 1).TrimStart() + ',' + argumentSequence; command = command.Substring(0, space).TrimEnd(); if (strictParsing) { string text = "Command \"" + command + "\" must be separated from its arguments by a comma in CSV files on line " + (l + 1).ToString() + " in file \"" + file + "\"."; options.Logger.Add(text); } } } } if (command.Length != 0) { // --- split into arguments and trim empty arguments from the end --- string[] arguments = argumentSequence.Split(','); for (int a = 0; a < arguments.Length; a++) { arguments[a] = arguments[a].Trim(); } int argumentCount = 0; for (int a = arguments.Length - 1; a >= 0; a--) { if (arguments[a].Length != 0) { argumentCount = a + 1; break; } } // --- process commands --- LineInformation lineInfo = new LineInformation(command, arguments, argumentCount, l + 1, fileInfo); string commandLower = command.ToLowerInvariant(); switch (commandLower) { case "[meshbuilder]": case "createmeshbuilder": { if (strictParsing) { CheckCommand(command, "[MeshBuilder]", "CreateMeshBuilder", lineInfo); CheckArgumentCount(command, argumentCount, 0, 0, lineInfo); } meshBuilders.Add(currentMeshBuilder); currentMeshBuilder = new MeshBuilder(); meshBuilderPresent = true; } break; case "vertex": case "addvertex": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckCommand(command, "Vertex", "AddVertex", lineInfo); CheckArgumentCount(command, argumentCount, 0, 8, lineInfo); } double positionX = GetDoubleFromArgument(0, "positionX", 0.0, lineInfo); double positionY = GetDoubleFromArgument(1, "positionY", 0.0, lineInfo); double positionZ = GetDoubleFromArgument(2, "positionZ", 0.0, lineInfo); double normalX = GetDoubleFromArgument(3, "normalX", 0.0, lineInfo); double normalY = GetDoubleFromArgument(4, "normalY", 0.0, lineInfo); double normalZ = GetDoubleFromArgument(5, "normalZ", 0.0, lineInfo); double textureX = GetDoubleFromArgument(6, "textureX", 0.0, lineInfo); double textureY = GetDoubleFromArgument(7, "textureY", 0.0, lineInfo); MeshBuilderVertex vertex = new MeshBuilderVertex(new Vector3d(positionX, positionY, positionZ), new Vector3d(normalX, normalY, normalZ), new Vector2d(textureX, textureY)); currentMeshBuilder.Vertices.Add(vertex); } break; case "face": case "face2": case "addface": case "addface2": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); } bool face2 = commandLower[commandLower.Length - 1] == '2'; if (strictParsing) { string suffix = face2 ? "2" : string.Empty; CheckCommand(command, "Face" + suffix, "AddFace" + suffix, lineInfo); } bool success = CheckArgumentCount(command, argumentCount, 3, int.MaxValue, lineInfo); int[] indices = new int[argumentCount]; for (int i = 0; i < argumentCount; i++) { if (!TryGetInt32FromArgument(i, "vertex" + (i + 1).ToString(), 0, currentMeshBuilder.Vertices.Count - 1, -1, false, lineInfo, out indices[i])) { success = false; } } if (success) { currentMeshBuilder.Faces.Add(new MeshBuilderFace(0, indices, lineInfo.LineNumber)); if (face2) { Array.Reverse(indices); MeshBuilderFace face = new MeshBuilderFace(0, indices, lineInfo.LineNumber); face.Normals = MeshBuilderFaceNormals.Inverse; currentMeshBuilder.Faces.Add(face); } } } break; case "cube": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckArgumentCount(command, argumentCount, 0, 3, lineInfo); } double x = GetDoubleFromArgument(0, "x", 0.0, lineInfo); double y = GetDoubleFromArgument(1, "y", x, lineInfo); double z = GetDoubleFromArgument(2, "z", x, lineInfo); currentMeshBuilder.AddCube(x, y, z, lineInfo.LineNumber); } break; case "cylinder": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckArgumentCount(command, argumentCount, 1, 4, lineInfo); } int numVertices; bool success = TryGetInt32FromArgument(0, "numVertices", 2, int.MaxValue, 0, false, lineInfo, out numVertices); double upper = GetDoubleFromArgument(1, "upper", 0.0, lineInfo); double lower = GetDoubleFromArgument(2, "lower", 0.0, lineInfo); double height = GetDoubleFromArgument(3, "height", 0.0, lineInfo); if (success) { currentMeshBuilder.AddCylinder(numVertices, upper, lower, height, lineInfo.LineNumber); } } break; case "[texture]": case "generatenormals": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckCommand(command, "[Texture]", "GenerateNormals", lineInfo); CheckArgumentCount(command, argumentCount, 0, 0, lineInfo); } } break; case "translate": case "translateall": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckArgumentCount(command, argumentCount, 0, 3, lineInfo); } double x = GetDoubleFromArgument(0, "x", 0.0, lineInfo); double y = GetDoubleFromArgument(1, "y", 0.0, lineInfo); double z = GetDoubleFromArgument(2, "z", 0.0, lineInfo); Vector3d offset = new Vector3d(x, y, z); currentMeshBuilder.Translate(offset); if (commandLower == "translateall") { foreach (MeshBuilder meshBuilder in meshBuilders) { meshBuilder.Translate(offset); } } } break; case "scale": case "scaleall": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckArgumentCount(command, argumentCount, 0, 3, lineInfo); } double x = GetDoubleFromArgument(0, "x", 1.0, lineInfo); double y = GetDoubleFromArgument(1, "y", 1.0, lineInfo); double z = GetDoubleFromArgument(2, "z", 1.0, lineInfo); Vector3d factor = new Vector3d(x, y, z); currentMeshBuilder.Scale(factor); if (commandLower == "scaleall") { foreach (MeshBuilder meshBuilder in meshBuilders) { meshBuilder.Scale(factor); } } } break; case "rotate": case "rotateall": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckArgumentCount(command, argumentCount, 0, 4, lineInfo); } double x = GetDoubleFromArgument(0, "x", 0.0, lineInfo); double y = GetDoubleFromArgument(1, "y", 0.0, lineInfo); double z = GetDoubleFromArgument(2, "z", 0.0, lineInfo); double a = GetDoubleFromArgument(3, "angle", 0.0, lineInfo) * (Math.PI / 180.0); Vector3d direction = Vector3d.Normalize(new Vector3d(x, y, z)); if (direction.IsZero()) { direction = Vector3d.Right; } Vector2d angle = new Vector2d(Math.Cos(a), Math.Sin(a)); currentMeshBuilder.Rotate(direction, angle); if (commandLower == "rotateall") { foreach (MeshBuilder meshBuilder in meshBuilders) { meshBuilder.Rotate(direction, angle); } } } break; case "shear": case "shearall": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckArgumentCount(command, argumentCount, 0, 7, lineInfo); } double dx = GetDoubleFromArgument(0, "dx", 0.0, lineInfo); double dy = GetDoubleFromArgument(1, "dy", 0.0, lineInfo); double dz = GetDoubleFromArgument(2, "dz", 0.0, lineInfo); double sx = GetDoubleFromArgument(3, "sx", 0.0, lineInfo); double sy = GetDoubleFromArgument(4, "sy", 0.0, lineInfo); double sz = GetDoubleFromArgument(5, "sz", 0.0, lineInfo); double r = GetDoubleFromArgument(6, "ratio", 0.0, lineInfo); Vector3d direction = Vector3d.Normalize(new Vector3d(dx, dy, dz)); Vector3d shift = Vector3d.Normalize(new Vector3d(sx, sy, sz)); currentMeshBuilder.Shear(direction, shift, r); if (commandLower == "shearall") { foreach (MeshBuilder meshBuilder in meshBuilders) { meshBuilder.Shear(direction, shift, r); } } } break; case "color": case "setcolor": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckCommand(command, "Color", "SetColor", lineInfo); CheckArgumentCount(command, argumentCount, 0, 4, lineInfo); } double r, g, b, a; TryGetDoubleFromArgument(0, "red", 0.0, 255.0, 255.0, true, lineInfo, out r); TryGetDoubleFromArgument(1, "green", 0.0, 255.0, 255.0, true, lineInfo, out g); TryGetDoubleFromArgument(2, "blue", 0.0, 255.0, 255.0, true, lineInfo, out b); TryGetDoubleFromArgument(3, "alpha", 0.0, 255.0, 255.0, true, lineInfo, out a); Vector3f color = new Vector3f((float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f); for (int i = 0; i < currentMeshBuilder.Faces.Count; i++) { currentMeshBuilder.Faces[i].ReflectiveColor = color; currentMeshBuilder.Faces[i].Alpha = (float)a / 255.0f; } } break; case "emissivecolor": case "setemissivecolor": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckCommand(command, "EmissiveColor", "SetEmissiveColor", lineInfo); CheckArgumentCount(command, argumentCount, 0, 3, lineInfo); } double r, g, b; TryGetDoubleFromArgument(0, "red", 0.0, 255.0, 0.0, true, lineInfo, out r); TryGetDoubleFromArgument(1, "green", 0.0, 255.0, 0.0, true, lineInfo, out g); TryGetDoubleFromArgument(2, "blue", 0.0, 255.0, 0.0, true, lineInfo, out b); Vector3f color = new Vector3f((float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f); for (int i = 0; i < currentMeshBuilder.Faces.Count; i++) { currentMeshBuilder.Faces[i].EmissiveColor = color; } } break; case "blendmode": case "setblendmode": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckCommand(command, "BlendMode", "SetBlendMode", lineInfo); CheckArgumentCount(command, argumentCount, 0, 3, lineInfo); } string blendMode = argumentCount >= 1 && arguments[0].Length != 0 ? arguments[0] : "normal"; double glowHalfDistance; TryGetDoubleFromArgument(1, "glowHalfDistance", 0.0, double.MaxValue, 0.0, true, lineInfo, out glowHalfDistance); string glowAttenuationMode = argumentCount >= 3 && arguments[2].Length != 0 ? arguments[2] : "divideexponent2"; switch (blendMode.ToLowerInvariant()) { case "normal": break; case "additive": break; default: string text = "\"" + blendMode + "\" as argument 1 to command " + lineInfo.Command + " is not a valid blend mode on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; options.Logger.Add(text); break; } switch (glowAttenuationMode.ToLowerInvariant()) { case "divideexponent2": break; case "divideexponent4": break; default: string text = "\"" + blendMode + "\" as argument 3 to command " + lineInfo.Command + " is not a valid glow attenuation mode on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; options.Logger.Add(text); break; } // TODO: Not implemented. } break; case "load": case "loadtexture": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckCommand(command, "Load", "LoadTexture", lineInfo); CheckArgumentCount(command, argumentCount, 1, 2, lineInfo); } string daytimeTexture = null; string nighttimeTexture = null; if (argumentCount >= 1 && arguments[0].Length != 0) { daytimeTexture = arguments[0]; } if (argumentCount >= 2 && arguments[1].Length != 0) { nighttimeTexture = arguments[1]; } if (daytimeTexture != null) { currentMeshBuilder.DaytimeTexture = Platform.CombineFile(Path.GetDirectoryName(file), daytimeTexture); } // TODO: Nighttime textures. } break; case "transparent": case "setdecaltransparentcolor": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckCommand(command, "Transparent", "SetDecalTransparentColor", lineInfo); CheckArgumentCount(command, argumentCount, 0, 3, lineInfo); } int r, g, b; TryGetInt32FromArgument(0, "red", 0, 255, 0, true, lineInfo, out r); TryGetInt32FromArgument(1, "green", 0, 255, 0, true, lineInfo, out g); TryGetInt32FromArgument(2, "blue", 0, 255, 0, true, lineInfo, out b); currentMeshBuilder.TransparentColor = new Vector3b((byte)r, (byte)g, (byte)b); currentMeshBuilder.TransparentColorUsed = true; } break; case "coordinates": case "settexturecoordinates": { if (strictParsing) { CheckMeshBuilderPresence(command, lineInfo, ref meshBuilderPresent); CheckCommand(command, "Coordinates", "SetTextureCoordinates", lineInfo); CheckArgumentCount(command, argumentCount, 1, 3, lineInfo); } int v = -1; bool success; if (currentMeshBuilder.Vertices.Count == 0) { string text = lineInfo.Command + " cannot be used at this point because no vertices were defined in the mesh builder on line " + lineInfo.LineNumber.ToString() + " in file \"" + lineInfo.FileInfo.File + "\"."; options.Logger.Add(text); success = false; } else { success = TryGetInt32FromArgument(0, "vertex", 0, currentMeshBuilder.Vertices.Count - 1, 0, false, lineInfo, out v); } double x = GetDoubleFromArgument(1, "x", 0.0, lineInfo); double y = GetDoubleFromArgument(2, "y", 0.0, lineInfo); if (success) { currentMeshBuilder.Vertices[v].Texture = new Vector2d(x, y); } } break; default: { string text = "Unsupported command \"" + command + "\" found on line " + (l + 1).ToString() + " in file \"" + file + "\"."; options.Logger.Add(text); } break; } } } } meshBuilders.Add(currentMeshBuilder); currentMeshBuilder = null; // --- assemble mesh --- Dictionary<Vertex, int> hashedVertices = new Dictionary<Vertex, int>(); Dictionary<Material, int> hashedMaterials = new Dictionary<Material, int>(); List<Vertex> vertices = new List<Vertex>(); List<Material> materials = new List<Material>(); List<Face> faces = new List<Face>(); foreach (MeshBuilder meshBuilder in meshBuilders) { foreach (MeshBuilderFace meshBuilderFace in meshBuilder.Faces) { // --- generate normal --- Vector3d normal; { Vector3d a = meshBuilder.Vertices[meshBuilderFace.Vertices[0]].Position; Vector3d b = meshBuilder.Vertices[meshBuilderFace.Vertices[1]].Position; Vector3d c = meshBuilder.Vertices[meshBuilderFace.Vertices[2]].Position; normal = Vector3d.Normalize(Vector3d.Cross(b - a, c - a)); if (normal.IsZero()) { normal = Vector3d.Up; } } // --- vertices --- Vertex[] v = new Vertex[meshBuilderFace.Vertices.Length]; for (int i = 0; i < meshBuilderFace.Vertices.Length; i++) { MeshBuilderVertex meshBuilderVertex = meshBuilder.Vertices[meshBuilderFace.Vertices[i]]; v[i] = new Vertex((Vector3f)meshBuilderVertex.Position, (Vector3f)meshBuilderVertex.Normal, (Vector2f)meshBuilderVertex.Texture); if (meshBuilderFace.Normals == MeshBuilderFaceNormals.Generate || meshBuilderVertex.Normal.IsZero()) { v[i].Normal = (Vector3f)normal; } else if (meshBuilderFace.Normals == MeshBuilderFaceNormals.Inverse) { v[i].Normal = (Vector3f)(-meshBuilderVertex.Normal); } } int[] vertexIndices = new int[v.Length]; for (int i = 0; i < v.Length; i++) { if (!hashedVertices.TryGetValue(v[i], out vertexIndices[i])) { vertexIndices[i] = vertices.Count; vertices.Add(v[i]); hashedVertices.Add(v[i], vertexIndices[i]); } } // --- material --- Material material = new Material(); material.Alpha = meshBuilderFace.Alpha; material.EmissiveColor = meshBuilderFace.EmissiveColor; material.ReflectiveColor = meshBuilderFace.ReflectiveColor; if (meshBuilder.DaytimeTexture != null) { if (meshBuilder.TransparentColorUsed) { material.Texture = options.Manager.Add(meshBuilder.DaytimeTexture, meshBuilder.TransparentColor); } else { material.Texture = options.Manager.Add(meshBuilder.DaytimeTexture); } } int materialIndex; if (!hashedMaterials.TryGetValue(material, out materialIndex)) { materialIndex = materials.Count; materials.Add(material); hashedMaterials.Add(material, materialIndex); } // --- face --- Face face = new Face(vertexIndices, materialIndex, meshBuilderFace.LineNumber); faces.Add(face); } } return new Mesh(vertices.ToArray(), materials.ToArray(), faces.ToArray()); }