/// <summary> /// Randomly sets the depths of all the hexes in the grid. /// </summary> /// <param name="grid">The grid that has the noise generated on it</param> /// <param name="min">Minimum depth</param> /// <param name="max">Maximum depth</param> public static void GenerateNoise(HexGrid grid, int min, int max) { Hexagon[,] mGrid = grid.Grid; Random rand = new Random(); for (int i = 0; i < DEFAULT_MAP_WIDTH; i++) { for (int j = 0; j < DEFAULT_MAP_HEIGHT; j++) { mGrid[i, j].Depth = rand.Next(min, max); } } }
/// <summary> /// Initializes the control. /// </summary> protected override void Initialize() { mPreviousMouseState = Mouse.GetState(); IsDrawingModels = true; IsDrawingWireFrame = true; // Create a Vector Direction Marker vectorDirMarker = new VectorDirectionMarker(GraphicsDevice.Viewport.AspectRatio); // Create a hextube hexTube = new HexTube(); // Create a hexgrid hexGrid = new HexGrid(); HexHelper.GenerateNoise(hexGrid, 0, 3); //hexGrid.SmoothHexesDown(); //hexGrid.SetColorSchemeAll(Color.DarkSeaGreen, Color.DarkOrchid); hexGrid.ClusterColor(1, 4, Color.Red, Color.Pink); // Create our camera. camera = new Camera(GraphicsDevice.Viewport.AspectRatio); // Create our effect. effect = new BasicEffect(GraphicsDevice); // Enable to allow color effect.VertexColorEnabled = true; // Start the animation timer. timer = Stopwatch.StartNew(); // Hook the idle event to constantly redraw our animation. Application.Idle += delegate { Invalidate(); }; }
/// <summary> /// This method tries to draw a ray from the camera to where the user clicks on the screen. /// REVISIT: It needs some serious work. Theres a lot of weird offsets that makes the ray not draw quite right. /// </summary> /// <param name="device"></param> /// <param name="effect"></param> /// <param name="hexGrid"></param> /// <param name="mouseX">This X value must be adjusted based on the window location prior to this method</param> /// <param name="mouseY">This Y value must be adjusted based on the window location prior to this method</param> /// <param name="viewMatrix"></param> /// <param name="projectionMatrix"></param> /// <returns>The selected Hexagon. Returns null if it doesn't intersect anything</returns> public static Hexagon SelectHexagon(GraphicsDevice device, HexGrid hexGrid, int mouseX, int mouseY, Matrix viewMatrix, Matrix projectionMatrix, Vector3 cameraPosition) { // Uses the mouse coordinates to create a point in 2d space. // I think these offsets account for where the graphics window is inside the form // Though honestly I don't know for sure whats going wrong, because the offset of the // Graphics window offsets are closer to 12 x 106 // currently im using the camera position instead of nearsource. Vector3 nearsource = new Vector3((float)mouseX - 20, (float)mouseY - 150, 0f); Vector3 farsource = new Vector3((float)mouseX - 20, (float)mouseY - 150, 1f); Matrix world = Matrix.Identity; // Translates the points in 2d space into // Vector3 nearPoint = device.Viewport.Unproject(nearsource, projectionMatrix, viewMatrix, world); Vector3 farPoint = device.Viewport.Unproject(farsource, projectionMatrix, viewMatrix, world); // Create a ray from the near clip plane to the far clip plane. //Vector3 direction = farPoint - nearPoint; Vector3 direction = farPoint - cameraPosition; direction.Normalize(); //Ray pickRay = new Ray(nearPoint, direction); Ray pickRay = new Ray(cameraPosition, direction); globalRay = pickRay; List<Hexagon> candidates = new List<Hexagon>(); // Once we have the ray loop through it to find all the candidate hexagons. for (int i = 0; i < DEFAULT_MAP_WIDTH; i++) { for (int j = 0; j < DEFAULT_MAP_HEIGHT; j++) { // Set the bounding sphere for the grid to the correct location. hexGrid.Grid[i, j].SetBoundingXY(i, j); // Make a list of candidate hexes for selection. if (hexGrid.Grid[i, j].BoundingSphere.Intersects(pickRay) != null) { candidates.Add(hexGrid.Grid[i, j]); } } } if (candidates.Count == 0) // If we didn't find any hexes { return null; } else if (candidates.Count == 1) // If we found one hex { return candidates[0]; } else // If we found multiple hexes, pick the one closest to the camera. REVISIT // doesnt quite work right { Hexagon closest = candidates[0]; float minDist = Vector3.DistanceSquared(candidates[0].BoundingSphere.Center, cameraPosition); float tempDist; for (int i = 0; i < candidates.Count; i++) { tempDist = Vector3.DistanceSquared(candidates[i].BoundingSphere.Center, cameraPosition); if (minDist > tempDist) { minDist = tempDist; closest = candidates[i]; } } return closest; } }
/// <summary> /// Gets an array of Hexagons surronding the specified hex. /// Null hexes ARE in to the array! /// /// They are in this order: /// 0: Bottom, 1: Bottom Right, 2: Top Right, 3: Top, 4: Top Left, 5: Bottom Left /// </summary> /// <returns>An array of hexagons surronding the given hex, including null hexes.</returns> public static Hexagon[] SurrondingHexes(HexGrid grid, int x, int y) { Hexagon[] surrounding = new Hexagon[6]; bool even = x % 2 == 0; Hexagon[,] mGrid = grid.Grid; if (y > 0) surrounding[0] = mGrid[x, y - 1]; // Bottom if (y < DEFAULT_MAP_HEIGHT - 1) surrounding[3] = mGrid[x, y + 1]; // Top if (!even) { if (x < DEFAULT_MAP_WIDTH - 1) surrounding[1] = mGrid[x + 1, y]; // Bottom Right if (x < DEFAULT_MAP_WIDTH - 1 && y < DEFAULT_MAP_HEIGHT - 1) surrounding[2] = mGrid[x + 1, y + 1]; // Top Right if (x > 0 && y < DEFAULT_MAP_HEIGHT - 1) surrounding[4] = mGrid[x - 1, y + 1]; // Top Left if (x > 0) surrounding[5] = mGrid[x - 1, y]; // Bottom Left } else { if (x < DEFAULT_MAP_WIDTH - 1 && y > 0) surrounding[1] = mGrid[x + 1, y - 1]; // Bottom Right if (x < DEFAULT_MAP_WIDTH - 1 && y < DEFAULT_MAP_HEIGHT) surrounding[2] = mGrid[x + 1, y]; // Top Right if (x > 0 && y < DEFAULT_MAP_HEIGHT) surrounding[4] = mGrid[x - 1, y]; // Top Left if (x > 0 && y > 0) surrounding[5] = mGrid[x - 1, y - 1]; // Bottom Left } return surrounding; }
/// <summary> /// Currently does not work. Ideally it would set the vertices of /// a hex to be equal to their neighbors, giving priority to the lowest one. /// </summary> public static void SmoothHexesDown(HexGrid grid) { Hexagon[,] mGrid = grid.Grid; Random rand = new Random(); for (int i = 0; i < DEFAULT_MAP_WIDTH; i++) { for (int j = 0; j < DEFAULT_MAP_HEIGHT; j++) { for (int k = 0; k < 6; k++) { mGrid[i, j].SetVertexDepth(k, .01f * (float)rand.Next(100)); } } } }