public void SetHeight(int x, int y, int height) { int pos = map.CoordinateToIndex(x, y); Vector3 newVector = new Vector3(x * 4, height * 0.1f, y * 4); if (newVector != vertices[pos]) { vertices[pos] = newVector; HeightmapHandle handle = heightmapHandles[x, y]; handle.Slope = height; verticesChanged = true; dirty = true; } }
private void ResetState() { deselectedHandles.AddRange(currentFrameHoveredHandles); currentFrameHoveredHandles.Clear(); lastFrameHoveredHandles.Clear(); deselectedHandles.AddRange(selectedHandles); selectedHandles.Clear(); activeHandle = null; anchorHandle = null; if (anchorPlaneLine) { anchorPlaneLine.gameObject.SetActive(false); } state = HeightUpdaterState.Idle; GameManager.Instance.Map.CommandManager.UndoAction(); UpdateHandlesColors(); LayoutManager.Instance.CurrentCamera.RenderSelectionBox = false; }
public HeightmapHandle RaycastHandles() { Ray ray = LayoutManager.Instance.CurrentCamera.CreateMouseRay(); float closestDistance = float.MaxValue; HeightmapHandle closestHandle = null; foreach (HeightmapHandle heightmapHandle in heightmapHandles) { float distance = heightmapHandle.Raycast(ray); if (distance < 0) { continue; } if (distance < closestDistance) { closestDistance = distance; closestHandle = heightmapHandle; } } return(closestHandle); }
public void Initialize(Map map, bool cave) { meshFilter = GetComponent <MeshFilter>(); if (!meshFilter) { meshFilter = gameObject.AddComponent <MeshFilter>(); } meshRenderer = GetComponent <MeshRenderer>(); if (!meshRenderer) { meshRenderer = gameObject.AddComponent <MeshRenderer>(); } this.map = map; this.cave = cave; heightmapHandles = new HeightmapHandle[map.Width + 1, map.Height + 1]; heightmapRenderCache = new Dictionary <Color, List <Matrix4x4> >(); heightmapPropertiesCache = new Dictionary <Color, MaterialPropertyBlock>(); mesh = new Mesh(); mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; vertices = new Vector3[(map.Width + 1) * (map.Height + 1)]; uniformColors = new Color[(map.Width + 1) * (map.Height + 1)]; heightColors = new Color[(map.Width + 1) * (map.Height + 1)]; for (int i = 0; i <= map.Width; i++) { for (int i2 = 0; i2 <= map.Height; i2++) { int index = map.CoordinateToIndex(i, i2); vertices[index] = new Vector3(i * 4, 0, i2 * 4); uniformColors[index] = new Color(1, 1, 1); heightColors[index] = new Color(1, 1, 1); HeightmapHandle newHandle = new HeightmapHandle(new Vector2Int(i, i2), 0); heightmapHandles[i, i2] = newHandle; } } mesh.vertices = vertices; mesh.colors = uniformColors; int[] indices = new int[(map.Width + 1) * (map.Height + 1) * 4]; for (int i = 0; i < map.Width; i++) { for (int i2 = 0; i2 < map.Height; i2++) { int verticeIndex = map.CoordinateToIndex(i, i2); int arrayIndex = verticeIndex * 4; indices[arrayIndex] = verticeIndex; indices[arrayIndex + 1] = verticeIndex + 1; indices[arrayIndex + 2] = verticeIndex; indices[arrayIndex + 3] = verticeIndex + map.Height + 1; } } mesh.SetIndices(indices, MeshTopology.Lines, 0, true); meshFilter.sharedMesh = mesh; meshRenderer.sharedMaterial = GraphicsManager.Instance.SimpleDrawingMaterial; verticesChanged = false; dirty = false; }
private List <HeightmapHandle> UpdateHoveredHandlesComplexSelection(RaycastHit raycast) { List <HeightmapHandle> hoveredHandles = new List <HeightmapHandle>(); if (Input.GetMouseButtonDown(0)) { dragStartPos = LayoutManager.Instance.CurrentCamera.MousePosition; } dragEndPos = LayoutManager.Instance.CurrentCamera.MousePosition; if (state == HeightUpdaterState.Dragging) { if (Vector2.Distance(dragStartPos, dragEndPos) > 5) { LayoutManager.Instance.CurrentCamera.RenderSelectionBox = true; } Vector2 difference = dragEndPos - dragStartPos; float clampedDifferenceX = Mathf.Clamp(-difference.x, 0, float.MaxValue); float clampedDifferenceY = Mathf.Clamp(-difference.y, 0, float.MaxValue); Vector2 clampedDifference = new Vector2(clampedDifferenceX, clampedDifferenceY); Vector2 selectionStart = dragStartPos - clampedDifference; Vector2 selectionEnd = dragEndPos - dragStartPos + clampedDifference * 2; LayoutManager.Instance.CurrentCamera.SelectionBoxPosition = selectionStart; LayoutManager.Instance.CurrentCamera.SelectionBoxSize = selectionEnd; Vector2 viewportStart = selectionStart / LayoutManager.Instance.CurrentCamera.Screen.GetComponent <RectTransform>().sizeDelta; Vector2 viewportEnd = selectionEnd / LayoutManager.Instance.CurrentCamera.Screen.GetComponent <RectTransform>().sizeDelta; Rect viewportRect = new Rect(viewportStart, viewportEnd); Camera checkedCamera = LayoutManager.Instance.CurrentCamera.AttachedCamera; for (int i = 0; i <= GameManager.Instance.Map.Width; i++) { for (int i2 = 0; i2 < GameManager.Instance.Map.Height; i2++) { float height = GameManager.Instance.Map[i, i2].GetHeightForFloor(LayoutManager.Instance.CurrentCamera.Floor) * 0.1f; Vector2 viewportLocation = checkedCamera.WorldToViewportPoint(new Vector3(i * 4, height, i2 * 4)); if (viewportRect.Contains(viewportLocation)) { hoveredHandles.Add(GameManager.Instance.Map.SurfaceGridMesh.GetHandle(i, i2)); } } } } if (Input.GetMouseButtonUp(0)) { LayoutManager.Instance.CurrentCamera.RenderSelectionBox = false; } if (hoveredHandles.Count == 0) { HeightmapHandle heightmapHandle = raycast.transform ? GameManager.Instance.Map.SurfaceGridMesh.RaycastHandles() : null; if (heightmapHandle != null) { hoveredHandles.Add(heightmapHandle); } } return(hoveredHandles); }
private void UpdateCreateRamps() { Map map = GameManager.Instance.Map; float dragSensitivity = 0; float.TryParse(dragSensitivityInput.text, NumberStyles.Any, CultureInfo.InvariantCulture, out dragSensitivity); bool respectSlopes = respectOriginalSlopesToggle.isOn; if (state == HeightUpdaterState.Recovering) { state = HeightUpdaterState.Idle; } if (Input.GetMouseButtonDown(0)) { if (currentFrameHoveredHandles.Count == 1 && selectedHandles.Contains(currentFrameHoveredHandles[0])) { if (anchorHandle != null && anchorHandle != currentFrameHoveredHandles[0]) { activeHandle = currentFrameHoveredHandles[0]; } else { anchorHandle = currentFrameHoveredHandles[0]; } state = HeightUpdaterState.Manipulating; } else if (Input.GetKey(KeyCode.LeftShift)) { state = HeightUpdaterState.Dragging; } else { deselectedHandles = selectedHandles; selectedHandles = new List <HeightmapHandle>(); anchorHandle = null; anchorPlaneLine.gameObject.SetActive(false); state = HeightUpdaterState.Dragging; } } if (Input.GetMouseButton(0)) { if (state == HeightUpdaterState.Manipulating) { if (activeHandle != null && anchorHandle != null) { map.CommandManager.UndoAction(); bool locked = anchorPlaneLine.gameObject.activeSelf; PlaneAlignment lockedAxis = anchorPlaneLine.Alignment; int originalHeight = map[anchorHandle.TileCoords].SurfaceHeight; int heightDelta = (int)((dragEndPos.y - dragStartPos.y) * dragSensitivity); // instantly make smooth ramp from anchor handle to active handle if original slopes are not respected // turned off if original slopes are respected, because instantly making ramp is impractical in such case if (!respectSlopes) { heightDelta += map[activeHandle.TileCoords].SurfaceHeight - originalHeight; } Vector2Int manipulatedTileCoords = activeHandle.TileCoords; Vector2Int manipulatedAnchorCoords = GetAxisCorrectedAnchor(manipulatedTileCoords, anchorHandle.TileCoords, locked, lockedAxis); Vector2Int manipulatedDifference = manipulatedTileCoords - manipulatedAnchorCoords; foreach (HeightmapHandle heightmapHandle in selectedHandles) { Vector2Int tileCoords = heightmapHandle.TileCoords; Vector2Int anchorCoords = GetAxisCorrectedAnchor(tileCoords, anchorHandle.TileCoords, locked, lockedAxis); Vector2Int difference = tileCoords - anchorCoords; float deltaX = (float)difference.x / manipulatedDifference.x; if (float.IsNaN(deltaX) || float.IsInfinity(deltaX)) { deltaX = float.NegativeInfinity; } float deltaY = (float)difference.y / manipulatedDifference.y; if (float.IsNaN(deltaY) || float.IsInfinity(deltaY)) { deltaY = float.NegativeInfinity; } float delta = Mathf.Max(deltaX, deltaY); if (float.IsNegativeInfinity(delta)) { delta = 0; } if (respectSlopes) { map[tileCoords].SurfaceHeight += (int)(heightDelta * delta); } else { map[tileCoords].SurfaceHeight = originalHeight + (int)(heightDelta * delta); } } } else if (anchorHandle != null) { float anchorPositionX = anchorHandle.TileCoords.x * 4; float anchorPositionY = anchorHandle.TileCoords.y * 4; Vector2 anchorPosition = new Vector2(anchorPositionX, anchorPositionY); Vector3 raycastPoint = LayoutManager.Instance.CurrentCamera.CurrentRaycast.point; Vector2 raycastPosition = new Vector2(raycastPoint.x, raycastPoint.z); Vector2 positionDelta = raycastPosition - anchorPosition; if (positionDelta.magnitude > 4) { anchorPlaneLine.gameObject.SetActive(true); anchorPlaneLine.TileCoords = anchorHandle.TileCoords; bool horizontal = Mathf.Abs(positionDelta.x) > Mathf.Abs(positionDelta.y); anchorPlaneLine.Alignment = horizontal ? PlaneAlignment.Vertical : PlaneAlignment.Horizontal; } else { anchorPlaneLine.gameObject.SetActive(false); } } } } if (Input.GetMouseButtonUp(0)) { if (state == HeightUpdaterState.Dragging && Input.GetKey(KeyCode.LeftShift)) { selectedHandles.AddRange(lastFrameHoveredHandles); } else if (state == HeightUpdaterState.Dragging) { deselectedHandles = selectedHandles; selectedHandles = lastFrameHoveredHandles; } else if (state == HeightUpdaterState.Manipulating) { map.CommandManager.FinishAction(); activeHandle = null; } state = HeightUpdaterState.Idle; } if (Input.GetMouseButtonDown(1)) { if (state == HeightUpdaterState.Manipulating && activeHandle != null) { map.CommandManager.UndoAction(); activeHandle = null; state = HeightUpdaterState.Recovering; } else if (anchorHandle != null) { anchorHandle = null; anchorPlaneLine.gameObject.SetActive(false); state = HeightUpdaterState.Recovering; } else if (state == HeightUpdaterState.Idle) { deselectedHandles = selectedHandles; selectedHandles = new List <HeightmapHandle>(); } else { state = HeightUpdaterState.Recovering; } LayoutManager.Instance.CurrentCamera.RenderSelectionBox = false; } }
private void UpdateSelectAndDrag() { Map map = GameManager.Instance.Map; float dragSensitivity = 0; float.TryParse(dragSensitivityInput.text, NumberStyles.Any, CultureInfo.InvariantCulture, out dragSensitivity); bool respectSlopes = respectOriginalSlopesToggle.isOn; bool propertiesNeedSaving = false; if (Math.Abs(dragSensitivity - Properties.Instance.HeightDragSensitivity) > float.Epsilon) { Properties.Instance.HeightDragSensitivity = dragSensitivity; propertiesNeedSaving = true; } if (respectSlopes != Properties.Instance.HeightRespectOriginalSlopes) { Properties.Instance.HeightRespectOriginalSlopes = respectSlopes; propertiesNeedSaving = true; } if (propertiesNeedSaving) { Properties.Instance.SaveProperties(); } if (Input.GetMouseButtonDown(0)) { if (currentFrameHoveredHandles.Count == 1 && selectedHandles.Contains(currentFrameHoveredHandles[0])) { activeHandle = currentFrameHoveredHandles[0]; state = HeightUpdaterState.Manipulating; } else if (Input.GetKey(KeyCode.LeftShift)) { state = HeightUpdaterState.Dragging; } else { deselectedHandles = selectedHandles; selectedHandles = new List <HeightmapHandle>(); state = HeightUpdaterState.Dragging; } } if (Input.GetMouseButton(0)) { if (state == HeightUpdaterState.Manipulating) { map.CommandManager.UndoAction(); int originalHeight = map[activeHandle.TileCoords].SurfaceHeight; int heightDelta = (int)((dragEndPos.y - dragStartPos.y) * dragSensitivity); foreach (HeightmapHandle heightmapHandle in selectedHandles) { Vector2Int tileCoords = heightmapHandle.TileCoords; if (respectSlopes) { map[tileCoords].SurfaceHeight += heightDelta; } else { map[tileCoords].SurfaceHeight = originalHeight + heightDelta; } } } } if (Input.GetMouseButtonUp(0)) { if (state == HeightUpdaterState.Dragging && Input.GetKey(KeyCode.LeftShift)) { selectedHandles.AddRange(lastFrameHoveredHandles); } else if (state != HeightUpdaterState.Manipulating && state != HeightUpdaterState.Recovering) { deselectedHandles = selectedHandles; selectedHandles = lastFrameHoveredHandles; } else if (state == HeightUpdaterState.Manipulating) { map.CommandManager.FinishAction(); activeHandle = null; } state = HeightUpdaterState.Idle; } if (Input.GetMouseButtonDown(1)) { if (state == HeightUpdaterState.Idle) { deselectedHandles = selectedHandles; selectedHandles = new List <HeightmapHandle>(); } else if (state == HeightUpdaterState.Manipulating) { map.CommandManager.UndoAction(); activeHandle = null; state = HeightUpdaterState.Recovering; } else { state = HeightUpdaterState.Recovering; } LayoutManager.Instance.CurrentCamera.RenderSelectionBox = false; } }