public static void Main(string[] args) { var sectorGraphDescriptionStore = new SectorGraphDescriptionStore(); var snapshotCompiler = new TerrainSnapshotCompiler(sectorGraphDescriptionStore); var terrainService = new TerrainService(sectorGraphDescriptionStore, snapshotCompiler); // Add test sectors var leftSnd = terrainService.CreateSectorNodeDescription(SectorMetadataPresets.HashCircle2); // leftSnd.EnableDebugHighlight = true; leftSnd.WorldTransform = Matrix4x4.CreateScale(1000.0f / 60000.0f) * Matrix4x4.CreateTranslation(-1000, 0, 0); terrainService.AddSectorNodeDescription(leftSnd); var centerSnd = terrainService.CreateSectorNodeDescription(SectorMetadataPresets.Blank2D); centerSnd.EnableDebugHighlight = true; centerSnd.WorldTransform = Matrix4x4.CreateScale(1000.0f / 60000.0f); terrainService.AddSectorNodeDescription(centerSnd); /*+ [0] {(-30000, -18000)} OpenMOBA.Geometry.IntVector2 + [1] {(-30000, -6000)} OpenMOBA.Geometry.IntVector2 + [2] {(-6000, -6000)} OpenMOBA.Geometry.IntVector2 + [3] {(-6000, -18000)} OpenMOBA.Geometry.IntVector2 + [4] {(-30000, -18000)} OpenMOBA.Geometry.IntVector2 */ var rightSnd = terrainService.CreateSectorNodeDescription(SectorMetadataPresets.HashCircle2); rightSnd.WorldTransform = Matrix4x4.CreateScale(1000.0f / 60000.0f) * Matrix4x4.CreateTranslation(1000, 0, 0); terrainService.AddSectorNodeDescription(rightSnd); // edges between test sectors var rightTopSegment = new IntLineSegment2(new IntVector2(30000, 6000), new IntVector2(30000, 18000)); var leftTopSegment = new IntLineSegment2(new IntVector2(-30000, 6000), new IntVector2(-30000, 18000)); var rightBottomSegment = new IntLineSegment2(new IntVector2(30000, -18000), new IntVector2(30000, -6000)); var leftBottomSegment = new IntLineSegment2(new IntVector2(-30000, -18000), new IntVector2(-30000, -6000)); terrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build( leftSnd, centerSnd, rightTopSegment, leftTopSegment)); terrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build( centerSnd, leftSnd, leftTopSegment, rightTopSegment)); terrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build( leftSnd, centerSnd, rightBottomSegment, leftBottomSegment)); terrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build( centerSnd, leftSnd, leftBottomSegment, rightBottomSegment)); // terrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build( centerSnd, rightSnd, rightTopSegment, leftTopSegment)); terrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build( rightSnd, centerSnd, leftTopSegment, rightTopSegment)); terrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build( centerSnd, rightSnd, rightBottomSegment, leftBottomSegment)); terrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build( rightSnd, centerSnd, leftBottomSegment, rightBottomSegment)); // add some obstacles // terrainService.AddTemporaryHoleDescription(terrainService.CreateHoleDescription( // HoleStaticMetadata.CreateRectangleHoleMetadata(-500, 250, 60, 60, 0))); // terrainService.AddTemporaryHoleDescription(terrainService.CreateHoleDescription( // HoleStaticMetadata.CreateRectangleHoleMetadata(0, 130, 60, 60, 0))); for (var i = 0; i < 100; i++) { break; terrainService.AddTemporaryHoleDescription(terrainService.CreateHoleDescription( HoleStaticMetadata.CreateRectangleHoleMetadata( random.Next(-1500, 1500), random.Next(-500, 500), random.Next(10, 50), random.Next(10, 50), random.NextDouble() * Math.PI * 2))); } var terrainSnapshot = terrainService.CompileSnapshot(); var overlayNetwork = terrainSnapshot.OverlayNetworkManager.CompileTerrainOverlayNetwork(30); for (var i = 0; i < 360; i += 10) { var canvas = host.CreateAndAddCanvas(i); canvas.BatchDraw(() => { foreach (var terrainNode in overlayNetwork.TerrainNodes) { canvas.Transform = terrainNode.SectorNodeDescription.WorldTransform; canvas.DrawPolyNode(terrainNode.LandPolyNode, StrokeStyle.BlackHairLineSolid, StrokeStyle.DarkRedHairLineSolid); } foreach (var terrainNode in overlayNetwork.TerrainNodes) { canvas.Transform = terrainNode.SectorNodeDescription.WorldTransform; foreach (var outboundEdgeGroup in terrainNode.OutboundEdgeGroups) { foreach (var outboundEdge in outboundEdgeGroup.Value) { Console.WriteLine(outboundEdge.EdgeJob.SourceSegment); canvas.DrawLine(outboundEdge.EdgeJob.SourceSegment, StrokeStyle.CyanThick3Solid); } } } foreach (var terrainNode in overlayNetwork.TerrainNodes) { canvas.Transform = terrainNode.SectorNodeDescription.WorldTransform; foreach (var hole in terrainNode.LocalGeometryView.Job.DynamicHoles) { var(holeIncludedContours, holeExcludedContours) = hole.Value; canvas.DrawPolygonContours(holeIncludedContours, StrokeStyle.RedHairLineSolid); canvas.DrawPolygonContours(holeExcludedContours, StrokeStyle.OrangeHairLineSolid); } } int asdfa = -1; foreach (var terrainNode in overlayNetwork.TerrainNodes) { asdfa++; canvas.Transform = terrainNode.SectorNodeDescription.WorldTransform; if (terrainNode.SectorNodeDescription.EnableDebugHighlight) { var visibilityPolygonOrigin = IntVector2.FromRadiusAngle(50 * 60, i * Math.PI / 180) + new IntVector2(0, 0); canvas.DrawCrossSectorVisibilityPolygon(terrainNode, visibilityPolygonOrigin); } } }); } }
private IHoleStaticMetadata BuildRectangleHole(int x, int y, int width, int height, long rotationBits = -1) { var rotation = rotationBits == -1 ? 0.0 : BitConverter.Int64BitsToDouble(rotationBits); return(HoleStaticMetadata.CreateRectangleHoleMetadata(x, y, width, height, rotation)); }
public void Initialize() { // shift by something like -300, 0, 2700 //TerrainService.LoadMeshAsMap("Assets/bunny.obj", new DoubleVector3(0.015, -0.10, 0.0), new DoubleVector3(0, 0, 0), 30000); // TerrainService.LoadMeshAsMap("Assets/bunny_decimate_0_03.obj", new DoubleVector3(0.015, -0.10, 0.0), new DoubleVector3(0, 0, 0), 30000); // var sphereHole = TerrainService.CreateHoleDescription(new SphereHoleStaticMetadata { Radius = 500 }); // sphereHole.WorldTransform = Matrix4x4.CreateTranslation(-561.450012207031f, -1316.31005859375f, -116.25f); // GameEventQueueService.AddGameEvent(CreateAddTemporaryHoleEvent(new GameTime(0), sphereHole)); // GameEventQueueService.AddGameEvent(CreateRemoveTemporaryHoleEvent(new GameTime(200), sphereHole)); // TerrainService.LoadMeshAsMap("Assets/dragon.obj", new DoubleVector3(0.015, -0.10, 0.0), new DoubleVector3(0, 0, 0), 500); // TerrainService.LoadMeshAsMap("Assets/dragon_simp_15deg_decimate_collapse_0.01.obj", new DoubleVector3(0.015, -0.10, 0), new DoubleVector3(300, 0, -2700), 500); /* * TerrainService.LoadMeshAsMap("Assets/cube.obj", new DoubleVector3(0, 0, 0), new DoubleVector3(0, 0, 0), 500); * var holeDescription = TerrainService.CreateHoleDescription(new TerrainStaticMetadata { * LocalBoundary = new Rectangle(0, 0, 1000, 1000), * LocalIncludedContours = new List<Polygon2> { * Polygon2.CreateCircle(500, 500, 800) * } * }); * holeDescription.WorldTransform = Matrix4x4.CreateTranslation(-500, -500, 500); * TerrainService.AddTemporaryHoleDescription(holeDescription); * //[] */ /* * var sector = TerrainService.CreateSectorNodeDescription(SectorMetadataPresets.Blank2D); * sector.WorldTransform = Matrix4x4.Multiply(Matrix4x4.CreateScale(1), Matrix4x4.CreateTranslation(1 * 1000 - 1500, 0 * 1000 - 500, 0)); * TerrainService.AddSectorNodeDescription(sector); * * var left1 = new IntLineSegment2(new IntVector2(0, 200), new IntVector2(0, 400)); * var left2 = new IntLineSegment2(new IntVector2(0, 600), new IntVector2(0, 800)); * var right1 = new IntLineSegment2(new IntVector2(1000, 200), new IntVector2(1000, 400)); * var right2 = new IntLineSegment2(new IntVector2(1000, 600), new IntVector2(1000, 800)); * TerrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build(sector, sector, left2, left2)); */ /**/ var sectorSpanWidth = 1; var sectorSpanHeight = 1; var sectors = new SectorNodeDescription[sectorSpanHeight, sectorSpanWidth]; for (var y = 0; y < sectorSpanHeight; y++) { var rng = new Random(y); for (var x = 0; x < sectorSpanWidth; x++) { // var presets = new[] { SectorMetadataPresets.HashCircle2, SectorMetadataPresets.Test2D, SectorMetadataPresets.FourSquares2D }; // var presets = new[] { SectorMetadataPresets.HashCircle2, SectorMetadataPresets.Test2D, SectorMetadataPresets.HashCircle2 }; // var presets = new[] { SectorMetadataPresets.HashCircle2, SectorMetadataPresets.Blank2D, SectorMetadataPresets.HashCircle2 }; // var presets = new[] { SectorMetadataPresets.HashCircle2, SectorMetadataPresets.Test2D, SectorMetadataPresets.HashCircle2 }; var presets = new[] { SectorMetadataPresets.Test2D }; // var presets = new[] { SectorMetadataPresets.Blank2D, SectorMetadataPresets.Blank2D, SectorMetadataPresets.Blank2D }; var preset = presets[x]; //rng.Next(presets.Length)]; var sector = sectors[y, x] = TerrainService.CreateSectorNodeDescription(preset); //sector.WorldTransform = Matrix4x4.Multiply(Matrix4x4.CreateScale(1000.0f / 60000.0f), Matrix4x4.CreateTranslation(x * 1000 - 1000, y * 1000, 0)); sector.WorldTransform = Matrix4x4.Multiply(Matrix4x4.CreateScale(1000.0f / 60000.0f), Matrix4x4.CreateTranslation(0, 0, 0)); sector.WorldToLocalScalingFactor = 60000.0f / 1000.0f; TerrainService.AddSectorNodeDescription(sector); } } var left1 = new IntLineSegment2(new IntVector2(-30000, -18000), new IntVector2(-30000, -6000)); var left2 = new IntLineSegment2(new IntVector2(-30000, 6000), new IntVector2(-30000, 18000)); var right1 = new IntLineSegment2(new IntVector2(30000, -18000), new IntVector2(30000, -6000)); var right2 = new IntLineSegment2(new IntVector2(30000, 6000), new IntVector2(30000, 18000)); // var left1 = new IntLineSegment2(new IntVector2(0, 200), new IntVector2(0, 400)); // var left2 = new IntLineSegment2(new IntVector2(0, 600), new IntVector2(0, 800)); // var right1 = new IntLineSegment2(new IntVector2(1000, 200), new IntVector2(1000, 400)); // var right2 = new IntLineSegment2(new IntVector2(1000, 600), new IntVector2(1000, 800)); for (var y = 0; y < sectorSpanHeight; y++) { for (var x = 1; x < sectorSpanWidth; x++) { TerrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build(sectors[y, x - 1], sectors[y, x], right1, Clockness.CounterClockwise, left1, Clockness.Clockwise)); TerrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build(sectors[y, x - 1], sectors[y, x], right2, Clockness.CounterClockwise, left2, Clockness.Clockwise)); TerrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build(sectors[y, x], sectors[y, x - 1], left1, Clockness.Clockwise, right1, Clockness.CounterClockwise)); TerrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build(sectors[y, x], sectors[y, x - 1], left2, Clockness.Clockwise, right2, Clockness.CounterClockwise)); } } // var up1 = new IntLineSegment2(new IntVector2(200, 0), new IntVector2(400, 0)); // var up2 = new IntLineSegment2(new IntVector2(600, 0), new IntVector2(800, 0)); // var down1 = new IntLineSegment2(new IntVector2(200, 1000), new IntVector2(400, 1000)); // var down2 = new IntLineSegment2(new IntVector2(600, 1000), new IntVector2(800, 1000)); // for (var y = 1; y < sectorSpanHeight; y++) // for (var x = 0; x < sectorSpanWidth; x++) { // TerrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build(sectors[y - 1, x], sectors[y, x], down1, up1)); // TerrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build(sectors[y - 1, x], sectors[y, x], down2, up2)); // TerrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build(sectors[y, x], sectors[y - 1, x], up1, down1)); // TerrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build(sectors[y, x], sectors[y - 1, x], up2, down2)); // } // var donutOriginX = 0; // var donutOriginY = 0; // var donutThickness = 25; // var donutInnerSpan = 35; // var holeTsm = new TerrainStaticMetadata { // LocalBoundary = new Rectangle(donutOriginX, donutOriginY, 2 * donutThickness + donutInnerSpan, 2 * donutThickness + donutInnerSpan), // LocalIncludedContours = new[] { Polygon2.CreateRect(donutOriginX, donutOriginY, 2 * donutThickness + donutInnerSpan, 2 * donutThickness + donutInnerSpan) }, // LocalExcludedContours = new List<Polygon2> { // Polygon2.CreateRect(donutOriginX + donutThickness, donutOriginY + donutThickness, donutInnerSpan, donutInnerSpan) // } // }; // var hole = TerrainService.CreateHoleDescription(holeTsm); // hole.WorldTransform = Matrix4x4.Identity; // TerrainService.AddTemporaryHoleDescription(hole); /**/ var r = new Random(1); for (int i = 0; i < 30; i++) { break; var left = r.Next(0, 800); var top = r.Next(0, 800); var width = r.Next(100, 200); var height = r.Next(100, 200); var startTicks = r.Next(0, 500); var endTicks = r.Next(startTicks + 20, startTicks + 100); // account for test2d being flipped on Y back in the day top = 1000 - top - height; // account for create rectangle hole taking center x/y left += width / 2; top += height / 2; // center left -= 500; top -= 500; var holeMetadata = (PrismHoleStaticMetadata)HoleStaticMetadata.CreateRectangleHoleMetadata(left, top, width, height, 0); Trace.Assert(holeMetadata.LocalIncludedContours.Count == 1); var str = string.Join("; ", holeMetadata.LocalIncludedContours.First().Points.Select(p => p.ToString())); Console.WriteLine($"{left} {top} {width} {height} {startTicks} {endTicks} {str}"); var terrainHole = TerrainService.CreateHoleDescription(holeMetadata); GameEventQueueService.AddGameEvent(CreateAddTemporaryHoleEvent(new GameTime(startTicks), terrainHole)); GameEventQueueService.AddGameEvent(CreateRemoveTemporaryHoleEvent(new GameTime(endTicks), terrainHole)); } // for (int i = 0; i < 50; i++) { // var x = r.Next(0, 3000) - 1500; // var y = r.Next(0, 1000) - 500; // var width = r.Next(50, 200); // var height = r.Next(50, 200); // var startTicks = r.Next(0, 500); // var endTicks = r.Next(startTicks + 20, startTicks + 100); // // //if (i < 83 || i >= 85) continue; // //if (i != 83) continue; // // //var holeTsm = new TerrainStaticMetadata { // // LocalBoundary = new Rectangle(x, y, width, height), // // LocalIncludedContours = new[] { Polygon2.CreateRect(x, y, width, height) } // //}; // var terrainHole = TerrainService.CreateHoleDescription(HoleStaticMetadata.CreateRectangleHoleMetadata(x, y, width, height, 0)); // GameEventQueueService.AddGameEvent(CreateAddTemporaryHoleEvent(new GameTime(startTicks), terrainHole)); // GameEventQueueService.AddGameEvent(CreateRemoveTemporaryHoleEvent(new GameTime(endTicks), terrainHole)); // Console.WriteLine($"Event: {x} {y}, {width} {height} @ {startTicks}-{endTicks}"); // //if (i == 5) break; // } /* * for (int i = 0; i < 150; i++) { * break; * var x = r.Next(-520, -480); * var y = r.Next(80, 320); * var width = r.Next(10, 20); * var height = r.Next(10, 20); * var startTicks = r.Next(0, 500); * var endTicks = r.Next(startTicks + 20, startTicks + 100); * var rotation = r.NextDouble() * 2 * Math.PI; * * var contour = Polygon2.CreateRect(-width / 2, -height / 2, width, height).Points; * var transform = Matrix3x2.CreateRotation((float)rotation); * contour = contour.Map(p => Vector2.Transform(p.ToDoubleVector2().ToDotNetVector(), transform).ToOpenMobaVector().LossyToIntVector2()) * .Map(p => p + new IntVector2(x, y)) * .ToList(); * * var bounds = IntRect2.BoundingPoints(contour.ToArray()).ToDotNetRectangle(); * * var holeTsm = new PrismHoleStaticMetadata { * LocalBoundary = bounds, * LocalIncludedContours = new[] { new Polygon2(contour, false) } * }; * var terrainHole = TerrainService.CreateHoleDescription(holeTsm); * GameEventQueueService.AddGameEvent(CreateAddTemporaryHoleEvent(new GameTime(startTicks), terrainHole)); * GameEventQueueService.AddGameEvent(CreateRemoveTemporaryHoleEvent(new GameTime(endTicks), terrainHole)); * * Console.WriteLine($"Event: {x} {y}, {width} {height} {BitConverter.DoubleToInt64Bits(rotation)} @ {startTicks}-{endTicks}"); * // if (i == 5) break; * } * * for (var i = 0; i < 40; i++) { * var sphereHole = TerrainService.CreateHoleDescription(new SphereHoleStaticMetadata { Radius = 100 }); * sphereHole.WorldTransform = Matrix4x4.CreateTranslation(-500, 200, -120 + 240 * i / 40); * GameEventQueueService.AddGameEvent(CreateAddTemporaryHoleEvent(new GameTime(i * 15), sphereHole)); * GameEventQueueService.AddGameEvent(CreateRemoveTemporaryHoleEvent(new GameTime(i * 15 + 14), sphereHole)); * } * /**/ // //r.NextBytes(new byte[1337]); // //for (int i = 0; i < 20; i++) { // var w = r.Next(50, 100); // var h = r.Next(50, 100); // var poly = Polygon2.CreateRect(r.Next(800 + 80, 1100 - 80 - w) * 10 / 9, r.Next(520 - 40, 720 + 40 - h) * 10 / 9, w * 10 / 9, h * 10 / 9); // var startTicks = r.Next(0, 500); // var endTicks = r.Next(startTicks + 20, startTicks + 100); // var terrainHole = new DynamicTerrainHoleDescription { Polygons = new[] { poly } }; // GameEventQueueService.AddGameEvent(CreateAddTemporaryHoleEvent(new GameTime(startTicks), terrainHole)); // GameEventQueueService.AddGameEvent(CreateRemoveTemporaryHoleEvent(new GameTime(endTicks), terrainHole)); //} // //for (int i = 0; i < 20; i++) { // var w = r.Next(50, 100); // var h = r.Next(50, 100); // var poly = Polygon2.CreateRect(r.Next(800 + 80, 1100 - 80 - w) * 10 / 9, r.Next(180 - 40, 360 + 40 - h) * 10 / 9, w * 10 / 9, h * 10 / 9); // var startTicks = r.Next(0, 500); // var endTicks = r.Next(startTicks + 20, startTicks + 100); // var terrainHole = new DynamicTerrainHoleDescription { Polygons = new[] { poly } }; // GameEventQueueService.AddGameEvent(CreateAddTemporaryHoleEvent(new GameTime(startTicks), terrainHole)); // GameEventQueueService.AddGameEvent(CreateRemoveTemporaryHoleEvent(new GameTime(endTicks), terrainHole)); //} //var a = CreateTestEntity(new DoubleVector3(60 - 500, (1000 - 40) - 500, 0), 15, 80); //675 - 500 - 10, 175 - 500 - 10 //var b = CreateTestEntity(new DoubleVector3(675 - 500, (1000 - 175) - 500, 0), 15, 70); //675 - 500 - 10, 175 - 500 - 10 //var c = CreateTestEntity(new DoubleVector3(50 - 500, (1000 - 900) - 500, 0), 25, 60); //675 - 500 - 10, 175 - 500 - 10 //var d = CreateTestEntity(new DoubleVector3(50 - 500, (1000 - 500) - 500, 0), 25, 50); //675 - 500 - 10, 175 - 500 - 10 //var e = CreateTestEntity(new DoubleVector3(-1350, 200, 0), 30, 100); // var e = CreateTestEntity(new DoubleVector3(-650, 180, 0), 30, 100); // var c = CreateTestEntity(new DoubleVector3(50 - 500, 900 - 500, 0), 15, 60); // var d = CreateTestEntity(new DoubleVector3(50 - 500, 500 - 500, 0), 15, 50); //MovementSystemService.Pathfind(a, new DoubleVector3(930 - 500, (1000 - 300) - 500, 0)); //MovementSystemService.Pathfind(b, new DoubleVector3(825 - 500, (1000 - 300) - 500, 0)); //MovementSystemService.Pathfind(c, new DoubleVector3(950 - 500, (1000 - 475) - 500, 0)); //MovementSystemService.Pathfind(d, new DoubleVector3(80 - 500, (1000 - 720) - 500, 0)); //MovementSystemService.Pathfind(e, new DoubleVector3(1250, -80, 0)); // MovementSystemService.Pathfind(c, new DoubleVector3(950 - 500, 475 - 500, 0)); // MovementSystemService.Pathfind(d, new DoubleVector3(80 - 500, 720 - 500, 0)); // var benchmarkDestination = new DoubleVector3(1000, 325, 0.0); var benchmarkDestination = new DoubleVector3(425, 425, 0.0); var benchmarkUnitBaseSpeed = 100; var swarm = new Swarm { Destination = benchmarkDestination }; var swarmMeanRadius = 10.0f; for (var y = 0; y < 10; y++) { for (var x = 0; x < 10; x++) { // var swarmlingRadius = 10f; var swarmlingRadius = (float)Math.Round(5.0f + 10.0f * (float)r.NextDouble()); var p = new DoubleVector3(-450, -150, 0); var offset = new DoubleVector3(x * swarmMeanRadius * 2, y * swarmMeanRadius * 2, 0); var swarmling = CreateTestEntity(p + offset, swarmlingRadius, benchmarkUnitBaseSpeed); swarmling.MovementComponent.Swarm = swarm; swarm.Entities.Add(swarmling); } } //var optimal = CreateTestEntity(new DoubleVector3(50 + 9 * 10*2, 500, 0.0), 10, benchmarkUnitBaseSpeed); //MovementSystemService.Pathfind(optimal, benchmarkDestination); }