internal override Region ReadEntry(BinaryReaderEx br) { RegionType type = br.GetEnum8 <RegionType>(br.Position + br.VarintSize + 2); switch (type) { case RegionType.Region0: return(Region0s.EchoAdd(new Region.Region0(br))); case RegionType.Light: return(Lights.EchoAdd(new Region.Light(br))); case RegionType.StartPoint: return(StartPoints.EchoAdd(new Region.StartPoint(br))); case RegionType.Sound: return(Sounds.EchoAdd(new Region.Sound(br))); case RegionType.SFX: return(SFXs.EchoAdd(new Region.SFX(br))); case RegionType.Wind: return(Winds.EchoAdd(new Region.Wind(br))); case RegionType.EnvLight: return(EnvLights.EchoAdd(new Region.EnvLight(br))); case RegionType.Fog: return(Fogs.EchoAdd(new Region.Fog(br))); default: throw new NotImplementedException($"Unimplemented region type: {type}"); } }
public long SizeInCache() { return(Vertices.SizeOf() + Triangles.SizeOf() + Edges.SizeOf() + StartPoints.SizeOf()); }
public void DeleteStartPoint(int id) { if (StartPoints.ContainsKey(id)) { StartPoints.Remove(id); } }
/// <summary> /// Adds a region to the appropriate list for its type; returns the region. /// </summary> public Region Add(Region region) { switch (region) { case Region.Region0 r: Region0s.Add(r); break; case Region.Light r: Lights.Add(r); break; case Region.StartPoint r: StartPoints.Add(r); break; case Region.Sound r: Sounds.Add(r); break; case Region.SFX r: SFXs.Add(r); break; case Region.Wind r: Winds.Add(r); break; case Region.EnvLight r: EnvLights.Add(r); break; case Region.Fog r: Fogs.Add(r); break; default: throw new ArgumentException($"Unrecognized type {region.GetType()}.", nameof(region)); } return(region); }
public override void Clear() { base.Clear(); Edges.Clear(); StartPoints.Clear(); ModelName = ""; }
public void Write(BinaryWriter writer) { // Write a blank header now, and go back later and fix it up long HeaderPos = writer.BaseStream.Position; Header.DTMModelInternalName = ASCIIEncoding.ASCII.GetBytes(ModelName); if (Header.DTMModelInternalName.Length != HeaderConsts.kDTMInternalModelNameSize) { Array.Resize(ref Header.DTMModelInternalName, HeaderConsts.kDTMInternalModelNameSize); } Header.Write(writer); PadToBoundary(writer); Header.FileMajorVersion = Consts.TTMMajorVersion; Header.FileMinorVersion = Consts.TTMMinorVersion; Header.CoordinateUnits = 1; // Meters Header.VertexValueUnits = 1; // Meters Header.InterpolationMethod = 1; // Linear SetUpSizes(); Header.StartOffsetOfVertices = (int) writer.BaseStream.Position; Header.NumberOfVertices = Vertices.Count; Header.VertexRecordSize = (short) (2 * Header.VertexCoordinateSize + Header.VertexValueSize); (Vertices as TTMVertices).Write(writer, Header); PadToBoundary(writer); Header.StartOffsetOfTriangles = (int) writer.BaseStream.Position; Header.NumberOfTriangles = Triangles.Count; Header.TriangleRecordSize = (short) (3 * Header.VertexNumberSize + 3 * Header.TriangleNumberSize); Vertices.NumberVertices(); (Triangles as TTMTriangles).Write(writer, Header); PadToBoundary(writer); Header.StartOffsetOfEdgeList = (int) writer.BaseStream.Position; Header.NumberOfEdgeRecords = Edges.Count(); Header.EdgeRecordSize = Header.TriangleNumberSize; Edges.Write(writer, Header); PadToBoundary(writer); Header.StartOffsetOfStartPoints = (int) (writer.BaseStream.Position); Header.NumberOfStartPoints = StartPoints.Count(); Header.StartPointRecordSize = (short) (2 * Header.VertexCoordinateSize + Header.TriangleNumberSize); StartPoints.Write(writer, Header); // Fix up header long EndPos = writer.BaseStream.Position; writer.BaseStream.Position = HeaderPos; Header.Write(writer); writer.BaseStream.Position = EndPos; }
protected override void AddInitialCell(CPos location) { var cost = heuristic(location); Graph[location] = new CellInfo(CellStatus.Open, 0, cost, location); var connection = new GraphConnection(location, cost); OpenQueue.Add(connection); StartPoints.Add(connection); }
public void AddStartPoint(Rectangle bounds) { int nextId = StartPoints.Keys.OrderBy(k => k).LastOrDefault() + 1; StartPoints.Add(nextId, new StartPoint() { Bounds = bounds }); }
protected override void AddInitialCell(CPos location) { var cost = heuristic(location); Graph[location] = new CellInfo(0, cost, location, CellStatus.Open); var connection = new GraphConnection(location, cost); OpenQueue.Add(connection); StartPoints.Add(connection); considered.AddLast(new Pair <CPos, int>(location, 0)); }
/// <summary> /// Reads a TrimbleTINModel using the provided reader /// </summary> public void Read(BinaryReader reader, byte[] bytes) { var LoadErrMsg = ""; try { LoadErrMsg = "Error reading header"; Header.Read(reader); var identifier = System.Text.Encoding.ASCII.GetString(Header.FileSignature); if (identifier != Consts.TTM_FILE_IDENTIFIER) { throw new TTMFileReadException("File is not a Trimble TIN Model."); } // Check file version if (Header.FileMajorVersion != Consts.TTM_MAJOR_VERSION || Header.FileMinorVersion != Consts.TTM_MINOR_VERSION) { throw new TTMFileReadException($"TTM_Optimized.Read(): Unable to read this version {Header.FileMajorVersion}: {Header.FileMinorVersion} of Trimble TIN Model file. Expected version: { Consts.TTM_MAJOR_VERSION}: {Consts.TTM_MINOR_VERSION}"); } ModelName = ASCIIEncoding.ASCII.GetString(Header.DTMModelInternalName).TrimEnd(new[] { '\0' }); LoadErrMsg = "Error reading vertices"; reader.BaseStream.Position = Header.StartOffsetOfVertices; Vertices.Read(reader, Header); //Vertices.Read(bytes, Header.StartOffsetOfVertices, Header); LoadErrMsg = "Error reading triangles"; //reader.BaseStream.Position = Header.StartOffsetOfTriangles; //Triangles.Read(reader, Header); Triangles.Read(bytes, Header.StartOffsetOfTriangles, Header); LoadErrMsg = "Error reading edges"; reader.BaseStream.Position = Header.StartOffsetOfEdgeList; Edges.Read(reader, Header); LoadErrMsg = "Error reading start points"; reader.BaseStream.Position = Header.StartOffsetOfStartPoints; StartPoints.Read(reader, Header); } catch (TTMFileReadException) { throw; // pass it on } catch (Exception e) { throw new TTMFileReadException($"Exception at TTM loading phase {LoadErrMsg}", e); } }
internal override Region ReadEntry(BinaryReaderEx br) { RegionType type = br.GetEnum8 <RegionType>(br.Position + 0xA); switch (type) { case RegionType.Region0: var region0 = new Region.Region0(br); Region0s.Add(region0); return(region0); case RegionType.Light: var light = new Region.Light(br); Lights.Add(light); return(light); case RegionType.StartPoint: var startPoint = new Region.StartPoint(br); StartPoints.Add(startPoint); return(startPoint); case RegionType.Sound: var sound = new Region.Sound(br); Sounds.Add(sound); return(sound); case RegionType.SFX: var sfx = new Region.SFX(br); SFXs.Add(sfx); return(sfx); case RegionType.Wind: var wind = new Region.Wind(br); Winds.Add(wind); return(wind); case RegionType.EnvLight: var envLight = new Region.EnvLight(br); EnvLights.Add(envLight); return(envLight); case RegionType.Fog: var fog = new Region.Fog(br); Fogs.Add(fog); return(fog); default: throw new NotImplementedException($"Unimplemented region type: {type}"); } }
public void Add(IMsbRegion item) { switch (item) { case Region.Region0 r: Region0s.Add(r); break; case Region.Light r: Lights.Add(r); break; case Region.StartPoint r: StartPoints.Add(r); break; case Region.Sound r: Sounds.Add(r); break; case Region.SFX r: SFXs.Add(r); break; case Region.Wind r: Winds.Add(r); break; case Region.EnvLight r: EnvLights.Add(r); break; case Region.Fog r: Fogs.Add(r); break; default: throw new ArgumentException( message: "Item is not recognized", paramName: nameof(item)); } }
public void BuildStartPointList() { StartPoints.Clear(); if (Triangles.Count == 0) return; // How many start points do we want? int NumStartPoints = Math.Min(Math.Max((int) Math.Round(Math.Sqrt(Triangles.Count) / 2), 1), Consts.MaxStartPoints); // Use the centre points of this number of triangles evenly spaced throughout the job int TriNumOffset = (Triangles.Count / NumStartPoints) / 2; for (int StPtNum = 0; StPtNum < NumStartPoints; StPtNum++) { int TriangleNum = (StPtNum * Triangles.Count) / NumStartPoints + TriNumOffset; Debug.Assert(TriangleNum >= 0); XYZ Centroid = Triangles[TriangleNum].Centroid(); StartPoints.Add(new TTMStartPoint(Centroid.X, Centroid.Y, Triangles[TriangleNum])); } }
public void Read(BinaryReader reader) { string LoadErrMsg = ""; Loading = true; try { try { LoadErrMsg = "Error reading header"; Header = TTMHeader.NewHeader(); Header.Read(reader); var identifier = Encoding.ASCII.GetString(Header.FileSignature); if (identifier != Consts.TTMFileIdentifier) { throw new TTMFileReadException("File is not a Trimble TIN Model."); } // Check file version if (Header.FileMajorVersion != Consts.TTMMajorVersion || Header.FileMinorVersion != Consts.TTMMinorVersion) { throw new TTMFileReadException($"TTM.Read(): Unable to read this version {Header.FileMajorVersion}: {Header.FileMinorVersion} of Trimble TIN Model file. Expected version: { Consts.TTMMajorVersion}: {Consts.TTMMinorVersion}"); } Clear(); ModelName = ASCIIEncoding.ASCII.GetString(Header.DTMModelInternalName).TrimEnd(new []{'\0'}); LoadErrMsg = "Error reading vertices"; reader.BaseStream.Position = Header.StartOffsetOfVertices; (Vertices as TTMVertices).Read(reader, Header); LoadErrMsg = "Error reading triangles"; reader.BaseStream.Position = Header.StartOffsetOfTriangles; (Triangles as TTMTriangles).Read(reader, Header, Vertices); LoadErrMsg = "Error reading edges"; reader.BaseStream.Position = Header.StartOffsetOfEdgeList; Edges.Read(reader, Header, Triangles as TTMTriangles); LoadErrMsg = "Error reading start points"; reader.BaseStream.Position = Header.StartOffsetOfStartPoints; StartPoints.Read(reader, Header, Triangles); } catch (TTMFileReadException) { Clear(); throw; // pass it on } catch (Exception E) { Clear(); throw new TTMFileReadException($"Exception at TTM loading phase {LoadErrMsg}", E); } } finally { Loading = false; } }
private bool InitializePanel() { if (panel != null) { Walls.Clear(); StartPoints.Clear(); EndPoints.Clear(); renderedTetrisTextures.Clear(); PuzzleDimensions = new Point(panel.Width, panel.Height); // Calculation of puzzle sizes for current screen size int width = screenSize.X; int height = screenSize.Y; int maxPuzzleDimension = Math.Max(PuzzleDimensions.X, PuzzleDimensions.Y); int screenMinSize = Math.Min(width, height); int puzzleMaxSize = (int)(screenMinSize * PuzzleSpaceRatio(maxPuzzleDimension)); LineWidth = (int)(puzzleMaxSize * LineSizeRatio(maxPuzzleDimension)); BlockWidth = (int)(puzzleMaxSize * BlockSizeRatio(maxPuzzleDimension)); HalfLineWidthPoint = new Point(LineWidth / 2); LineWidthPoint = new Point(LineWidth); BlockSizePoint = new Point(BlockWidth); int endAppendixLength = (int)(BlockWidth * endPointLegth); int puzzleWidth = LineWidth * (PuzzleDimensions.X + 1) + BlockWidth * PuzzleDimensions.X; int puzzleHeight = LineWidth * (PuzzleDimensions.Y + 1) + BlockWidth * PuzzleDimensions.Y; int xMargin = (width - puzzleWidth) / 2; int yMargin = (height - puzzleHeight) / 2; Point margins = new Point(xMargin, yMargin); PuzzleConfig = new Rectangle(xMargin, yMargin, puzzleWidth, puzzleHeight); NodePadding = LineWidth + BlockWidth; // Creating walls hitboxes CreateHorizontalWalls(false); // Top walls CreateHorizontalWalls(true); // Bottom walls CreateVerticalWalls(false); // Left walls CreateVerticalWalls(true); // Right walls for (int i = 0; i < PuzzleDimensions.X; i++) { for (int j = 0; j < PuzzleDimensions.Y; j++) { Walls.Add(new Rectangle(xMargin + LineWidth * (i + 1) + BlockWidth * i, yMargin + LineWidth * (j + 1) + BlockWidth * j, BlockWidth, BlockWidth)); } } // Creating walls for broken edges var brokenEdges = panel.Edges.Where(x => x.State == EdgeState.Broken); foreach (Edge edge in brokenEdges) { Point nodeA = NodeIdToPoint(edge.Id % 100).Multiply(NodePadding) + margins; Point nodeB = NodeIdToPoint(edge.Id / 100).Multiply(NodePadding) + margins; Point middle = (nodeA + nodeB).Divide(2); Walls.Add(new Rectangle(middle, new Point(LineWidth))); } // Creating hitboxes for starting nodes foreach (Point start in GetStartNodes()) { StartPoints.Add(new Rectangle(xMargin + start.X * NodePadding - LineWidth, yMargin + start.Y * NodePadding - LineWidth, LineWidth * 3, LineWidth * 3)); } // Generate textures for tetris rules CreateTetrisRuleTextures(); #region === Inner methods region === // Returns a coef k: Total free space in pixels * k = puzzle size in pixels float PuzzleSpaceRatio(float puzzleDimension) => (float)(-0.0005 * Math.Pow(puzzleDimension, 4) + 0.0082 * Math.Pow(puzzleDimension, 3) - 0.0439 * Math.Pow(puzzleDimension, 2) + 0.1011 * puzzleDimension + 0.6875); // Returns a coef k: Puzzle size in pixels * k = block size in pixels float BlockSizeRatio(float puzzleDimension) => (float)(0.8563 * Math.Pow(puzzleDimension, -1.134)); // Returns a coef k: Puzzle size in pixels * k = line width in pixels float LineSizeRatio(float puzzleDimension) => - 0.0064f * puzzleDimension + 0.0859f; IEnumerable <Point> GetStartNodes() => panel.Nodes.Where(x => x.State == NodeState.Start).Select(x => NodeIdToPoint(x.Id)); IEnumerable <Point> GetEndNodesTop() { for (int i = 1; i < panel.Width; i++) { if (panel.Nodes[i].State == NodeState.Exit) { yield return(new Point(i, 0)); } } } IEnumerable <Point> GetEndNodesBot() { for (int i = 1; i < panel.Width; i++) { int index = panel.Height * (panel.Width + 1) + i; if (panel.Nodes[index].State == NodeState.Exit) { yield return(new Point(i, panel.Height)); } } } IEnumerable <Point> GetEndNodesLeft() { for (int j = 0; j < panel.Height + 1; j++) { int index = j * (panel.Width + 1); if (panel.Nodes[index].State == NodeState.Exit) { yield return(new Point(0, j)); } } } IEnumerable <Point> GetEndNodesRight() { for (int j = 0; j < panel.Height + 1; j++) { int index = j * (panel.Width + 1) + panel.Width; if (panel.Nodes[index].State == NodeState.Exit) { yield return(new Point(panel.Width, j)); } } } void CreateHorizontalWalls(bool isBottom) { int yStartPoint = isBottom ? yMargin + puzzleHeight : 0; var ends = isBottom ? GetEndNodesBot() : GetEndNodesTop(); if (ends.Count() == 0) { Walls.Add(new Rectangle(0, yStartPoint, width, yMargin)); } else { Walls.Add(new Rectangle(0, yStartPoint + (isBottom ? endAppendixLength : 0), width, yMargin - endAppendixLength)); int lastXPoint = 0; foreach (Point endPoint in ends) { int x = xMargin + endPoint.X * (NodePadding); Walls.Add(new Rectangle(lastXPoint, isBottom ? yStartPoint : (yMargin - endAppendixLength), x - lastXPoint, endAppendixLength)); EndPoints.Add(new EndPoint(new Rectangle(x, isBottom ? yStartPoint + endAppendixLength - LineWidth : (yMargin - endAppendixLength), LineWidth, LineWidth), isBottom ? Facing.Down : Facing.Up)); lastXPoint = x + LineWidth; } Walls.Add(new Rectangle(lastXPoint, isBottom ? yStartPoint : (yMargin - endAppendixLength), width - lastXPoint, endAppendixLength)); } } void CreateVerticalWalls(bool isRight) { int xStartPoint = isRight ? xMargin + puzzleWidth : 0; var ends = isRight ? GetEndNodesRight() : GetEndNodesLeft(); if (ends.Count() == 0) { Walls.Add(new Rectangle(xStartPoint, 0, xMargin, height)); } else { Walls.Add(new Rectangle(xStartPoint + (isRight ? endAppendixLength : 0), 0, xMargin - endAppendixLength, height)); int lastYPoint = 0; foreach (Point endPoint in ends) { int y = yMargin + endPoint.Y * (NodePadding); Walls.Add(new Rectangle(isRight ? xStartPoint : (xMargin - endAppendixLength), lastYPoint, endAppendixLength, y - lastYPoint)); EndPoints.Add(new EndPoint(new Rectangle(isRight ? xStartPoint + endAppendixLength - LineWidth : xMargin - endAppendixLength, y, LineWidth, LineWidth), isRight ? Facing.Right : Facing.Left)); lastYPoint = y + LineWidth; } Walls.Add(new Rectangle(isRight ? xStartPoint : (xMargin - endAppendixLength), lastYPoint, endAppendixLength, height - lastYPoint)); } } void CreateTetrisRuleTextures() { // Render shape into texture for each tetris rule var tetrisBlocks = panel.Blocks.Where(x => x.Rule is TetrisRule).ToList(); if (tetrisBlocks.Count > 0) { int maxDimension = tetrisBlocks.Select(x => x.Rule as TetrisRule).Select(x => Math.Max(x.Shape.GetLength(0), x.Shape.GetLength(1))).Max(); if (maxDimension < 3) { maxDimension++; } tetrisTextureSize = new Point((maxDimension + 1) * texTetris[0].Width); foreach (Block block in tetrisBlocks) { TetrisRule rule = block.Rule as TetrisRule; bool[,] shape = rule.Shape; // If shape is rotatable, then rotate it randomly before render if (rule is TetrisRotatableRule r) { shape = TetrisRotatableRule.RotateShapeCW(shape, rnd.Next(0, 4)); } // Draw shape on a texture RenderTarget2D texture = CreateTetrisTexture(shape, rule is TetrisRotatableRule, rule.IsSubtractive); // Save it to the dictionary renderedTetrisTextures.Add(block.Id, texture); } } } #endregion return(true); } return(false); }