internal List <Vector3> Get_sensitive_vertices(GameObject rmc) { List <Vector3> sensitive_vertices = new List <Vector3>(); // suppose MeshVerts returns nxm unconstrained mesh Vector3[] verts = Build.GetMeshVerts(rmc); Quarter[] tile_quarters = Quarter.Generate_All_Quarters(rmc); for (int index = 0; index < verts.Length; index++) { Vector3 v = rmc.transform.TransformPoint(verts[index]); v.x = Mathf.Round(v.x); v.z = Mathf.Round(v.z); if (!Consts.IsWithinMapBounds(v)) { continue; } if (v.x % 4 == 0 && v.z % 4 == 0) { sensitive_vertices.Add(v); continue; } // find a quarter that given vertex belongs to and get information about restriction pattern Quarter quarter = tile_quarters.Aggregate( (minItem, nextItem) => Consts.Distance(minItem.pos, v) < Consts.Distance(nextItem.pos, v) ? minItem : nextItem); if (quarter.qt.Unrestricted()) { sensitive_vertices.Add(v); } else if (quarter.qt.Both_restricted()) { if (quarter.original_grid.Contains(Consts.PosToIndex(v)) && !Consts.Lies_on_any_restricted_borders(v, quarter)) { sensitive_vertices.Add(v); } } else if (quarter.qt.Horizontal_restricted()) { if (quarter.original_grid.Contains(Consts.PosToIndex(v)) && !Consts.Lies_on_restricted_border(v, BorderType.Horizontal, quarter)) { sensitive_vertices.Add(v); } } else if (quarter.qt.Vertical_restricted()) { if (quarter.original_grid.Contains(Consts.PosToIndex(v)) && !Consts.Lies_on_restricted_border(v, BorderType.Vertical, quarter)) { sensitive_vertices.Add(v); } } } return(sensitive_vertices); }
private void FreeElevation() { // Highlight.pos is center vertex if (Highlight.pos.x != InitialPos.x || Highlight.pos.z != InitialPos.z) { // vertex -> vertex InitialPos = Highlight.pos; TargetSetHeights.Clear(); } HashSet <int> indexes = new HashSet <int>(); for (float z = Highlight.pos.z - RadiusSlider.value; z <= Highlight.pos.z + RadiusSlider.value; z++) { for (float x = Highlight.pos.x - RadiusSlider.value; x <= Highlight.pos.x + RadiusSlider.value; x++) { if (Consts.IsWithinMapBounds(x, z)) { int idx = Consts.PosToIndex((int)x, (int)z); Vector3 currentpos = Consts.IndexToPos(idx); float dist = Consts.Distance(currentpos, Highlight.pos); if (Mathf.Round(dist) > RadiusSlider.value - 1) { continue; } float TargetSetHeight; if (TargetSetHeights.ContainsKey(idx)) { TargetSetHeight = TargetSetHeights[idx]; } else { float Hdiff = Consts.SliderValue2RealHeight(HeightSlider.value) - currentpos.y; TargetSetHeight = currentpos.y + Hdiff * Consts.Smoothstep(0, 1, (RadiusSlider.value - dist) / RadiusSlider.value); TargetSetHeights.Add(idx, TargetSetHeight); } Consts.former_heights[idx] += (TargetSetHeight - currentpos.y) * Mathf.Pow(IntensitySlider.value * 5, 2) / 10000; Consts.current_heights[idx] = Consts.former_heights[idx]; UndoBuffer.AddVertexPair(currentpos, Consts.IndexToPos(idx)); indexes.Add(idx); } } } Consts.UpdateMapColliders(indexes); //Search for any tiles RaycastHit[] hits = Physics.BoxCastAll(new Vector3(Highlight.pos.x, Consts.MAX_H, Highlight.pos.z), new Vector3(RadiusSlider.value + .5f, 1, RadiusSlider.value + .5f), Vector3.down, Quaternion.identity, Consts.RAY_H, 1 << 9); List <GameObject> hitsList = hits.Select(hit => hit.transform.gameObject).ToList(); Build.UpdateTiles(hitsList); }
private void Smoothing() { HashSet <int> indexes = new HashSet <int>(); for (float z = Highlight.pos.z - RadiusSlider.value; z <= Highlight.pos.z + RadiusSlider.value; z++) { for (float x = Highlight.pos.x - RadiusSlider.value; x <= Highlight.pos.x + RadiusSlider.value; x++) { if (Consts.IsWithinMapBounds(x, z)) { int idx = Consts.PosToIndex((int)x, (int)z); Vector3 currentpos = Consts.IndexToPos(idx); float dist = Consts.Distance(currentpos, Highlight.pos); if (Mathf.Round(dist) > RadiusSlider.value - 1) { continue; } float height_sum = 0; for (float xx = currentpos.x - 1; xx <= currentpos.x + 1; xx++) { for (float zz = currentpos.z - 1; zz <= currentpos.z + 1; zz++) { if (xx == currentpos.x && zz == currentpos.z) { continue; } Vector3 neighbor_pos = new Vector3(xx, 0, zz); height_sum += Consts.current_heights[Consts.PosToIndex(neighbor_pos)]; } } float avg = height_sum / 8f; Vector3 for_buffer = Consts.IndexToPos(idx); Consts.current_heights[idx] += (avg - Consts.current_heights[idx]) * Mathf.Pow(IntensitySlider.value * 5, 2) / 10000; Consts.former_heights[idx] = Consts.current_heights[idx]; UndoBuffer.AddVertexPair(for_buffer, Consts.IndexToPos(idx)); indexes.Add(idx); } } } Consts.UpdateMapColliders(indexes); //Search for any tiles RaycastHit[] hits = Physics.BoxCastAll(new Vector3(Highlight.pos.x, Consts.MAX_H, Highlight.pos.z), new Vector3(RadiusSlider.value + 1, 1, RadiusSlider.value), Vector3.down, Quaternion.identity, Consts.RAY_H, 1 << 9); List <GameObject> hitsList = hits.Select(hit => hit.transform.gameObject).ToList(); Build.UpdateTiles(hitsList); }
private void Amplification(int dir = 1) { // Highlight.pos is center vertex HashSet <int> indexes = new HashSet <int>(); for (float z = Highlight.pos.z - RadiusSlider.value; z <= Highlight.pos.z + RadiusSlider.value; z++) { for (float x = Highlight.pos.x - RadiusSlider.value; x <= Highlight.pos.x + RadiusSlider.value; x++) { if (Consts.IsWithinMapBounds(x, z)) { int idx = Consts.PosToIndex((int)x, (int)z); float heightdiff = Consts.current_heights[idx] - Consts.SliderValue2RealHeight(HeightSlider.value); float dist = Consts.Distance(Consts.IndexToPos(idx), Highlight.pos); if (Mathf.Round(dist) > RadiusSlider.value - 1) { continue; } Vector3 for_buffer = Consts.IndexToPos(idx); Consts.former_heights[idx] += dir * heightdiff * Mathf.Pow(IntensitySlider.value * 2, 2) / 20000 * Consts.Smoothstep(0, 1, (RadiusSlider.value - dist) / RadiusSlider.value); Consts.current_heights[idx] = Consts.former_heights[idx]; UndoBuffer.AddVertexPair(for_buffer, Consts.IndexToPos(idx)); indexes.Add(idx); } } } Consts.UpdateMapColliders(indexes); //Search for any tiles RaycastHit[] hits = Physics.BoxCastAll(new Vector3(Highlight.pos.x, Consts.MAX_H, Highlight.pos.z), new Vector3(RadiusSlider.value + 1, 1, RadiusSlider.value), Vector3.down, Quaternion.identity, Consts.RAY_H, 1 << 9); List <GameObject> hitsList = hits.Select(hit => hit.transform.gameObject).ToList(); Build.UpdateTiles(hitsList); }
/// <summary> /// You need to add borders to vault before calling this /// </summary> static bool Calculate_All_RMC_points(GameObject rmc) { // suppose MeshVerts returns nxm unconstrained mesh Vector3[] verts = GetMeshVerts(rmc); Vector3 pos = Vpos2tpos(rmc); Quarter[] tile_quarters = Quarter.Generate_Quarters(rmc); for (int index = 0; index < verts.Length; index++) { Vector3Int v = Vector3Int.RoundToInt(rmc.transform.TransformPoint(verts[index])); if (!Consts.IsWithinMapBounds(v)) { continue; } // find a quarter that given vertex belongs to and get information about restriction pattern Quarter quarter = tile_quarters.Aggregate( (minItem, nextItem) => Consts.Distance(minItem.pos, v) < Consts.Distance(nextItem.pos, v) ? minItem : nextItem); if (quarter.qt.Unrestricted()) { verts[index].y = Consts.current_heights[Consts.PosToIndex(v)]; } else if (quarter.qt.Both_restricted()) { if (Consts.Lies_on_restricted_border(v, BorderType.Horizontal, quarter)) { verts[index].y = Calculate_horizontal_height(v); } else if (Consts.Lies_on_restricted_border(v, BorderType.Vertical, quarter)) { verts[index].y = Calculate_vertical_height(v); } else if (quarter.original_grid.Contains(Consts.PosToIndex(v))) { verts[index].y = Consts.current_heights[Consts.PosToIndex(v)]; } else { if (quarter.original_grid.Contains(Consts.PosToIndex(new Vector3(v.x / 4 * 4, v.y, v.z)))) { verts[index].y = Calculate_horizontal_height(v); } else if (quarter.original_grid.Contains(Consts.PosToIndex(new Vector3(v.x, v.y, v.z / 4 * 4)))) { verts[index].y = Calculate_vertical_height(v); } else { verts[index].y = Razor_both_restricted_formula(v); } } } else if (quarter.qt.Horizontal_restricted()) { if (!quarter.original_grid.Contains(Consts.PosToIndex(v)) || Consts.Lies_on_restricted_border(v, BorderType.Horizontal, quarter)) { verts[index].y = Calculate_horizontal_height(v); } else { verts[index].y = Consts.current_heights[Consts.PosToIndex(v)]; } } else if (quarter.qt.Vertical_restricted()) { if (!quarter.original_grid.Contains(Consts.PosToIndex(v)) || Consts.Lies_on_restricted_border(v, BorderType.Vertical, quarter)) { verts[index].y = Calculate_vertical_height(v); } else { verts[index].y = Consts.current_heights[Consts.PosToIndex(v)]; } } Consts.current_heights[Consts.PosToIndex(v)] = verts[index].y; if (float.IsNaN(verts[index].y) || float.IsInfinity(verts[index].y)) { return(false); } } UpdateMeshes(rmc, verts); return(true); }
private void RectangularElevation() { if (P1.x == -1) { // Get initial position and set znacznik there P1 = Highlight.pos; P1_marker = GameObject.CreatePrimitive(PrimitiveType.Cube); P1_marker.transform.localScale = new Vector3(.25f, 1, .25f); P1_marker.transform.position = Highlight.pos; } else { // Time to get second position Vector3 P2 = Highlight.pos; Vector3 BL = new Vector3(Mathf.Min(P1.x, P2.x), 0, Mathf.Min(P1.z, P2.z)); Vector3 TR = new Vector3(Mathf.Max(P1.x, P2.x), 0, Mathf.Max(P1.z, P2.z)); HashSet <int> indexes = new HashSet <int>(); for (float z = BL.z - (int)RadiusSlider.value; z <= TR.z + RadiusSlider.value; z++) { for (float x = BL.x - (int)RadiusSlider.value; x <= TR.x + RadiusSlider.value; x++) { if (Consts.IsWithinMapBounds(x, z)) { int idx = Consts.PosToIndex((int)x, (int)z); Vector3 currentpos = Consts.IndexToPos(idx); if (x >= BL.x && x <= TR.x && z >= BL.z && z <= TR.z) { Consts.former_heights[idx] = Consts.SliderValue2RealHeight(HeightSlider.value); } else { Vector3 Closest = GetClosestEdgeVertex(currentpos, BL, TR); float dist = Consts.Distance(currentpos, Closest); if (Mathf.Round(dist) > RadiusSlider.value - 1) { continue; } float Hdiff = Consts.SliderValue2RealHeight(HeightSlider.value) - Consts.current_heights[idx]; Consts.former_heights[idx] += Hdiff * Consts.Smoothstep(0, 1, (RadiusSlider.value - dist) / RadiusSlider.value); } Consts.current_heights[idx] = Consts.former_heights[idx]; UndoBuffer.AddVertexPair(currentpos, Consts.IndexToPos(idx)); indexes.Add(idx); } } } Consts.UpdateMapColliders(indexes); Vector3 center = new Vector3(0.5f * (P1.x + P2.x), Consts.MAX_H, 0.5f * (P1.z + P2.z)); Vector3 bounds = new Vector3(0.5f * Mathf.Abs(P1.x - P2.x) + RadiusSlider.value + .5f, 1f, 0.5f * Mathf.Abs(P1.z - P2.z) + RadiusSlider.value + .5f); RaycastHit[] hits = Physics.BoxCastAll(center, bounds, Vector3.down, Quaternion.identity, Consts.RAY_H, 1 << 9); Build.UpdateTiles(hits.Select(hit => hit.transform.gameObject).ToList()); UndoBuffer.ApplyTerrainOperation(); RemoveIndicator(); } Vector3 GetClosestEdgeVertex(Vector3 v, Vector3 LD, Vector3 PG) { Vector3 result = new Vector3(); if (v.x < LD.x) { result.x = LD.x; } else if (v.x > PG.x) { result.x = PG.x; } else { result.x = v.x; } if (v.z < LD.z) { result.z = LD.z; } else if (v.z > PG.z) { result.z = PG.z; } else { result.z = v.z; } return(result); } }