private TerrainQuad GetSelectedQuad() { if (quads == null) { return(null); } Vector2 mousePos = Event.current.mousePosition; Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); float bestT = -1.0f; TerrainQuad best = null; foreach (Dictionary <Vector3, TerrainQuad> quadDictionary in quads.Values) { foreach (TerrainQuad quad in quadDictionary.Values) { if (mode == EditMode.Painting && paintingNormal != quad.normal) { continue; } float t = MathHelper3D.RayDistanceForQuad(vertices, tris, ray, quad); if (t > 0.0f && (t < bestT || bestT == -1.0f)) { bestT = t; best = quad; } } } return(best); }
// creating a new quad mutates the tri/vert/uv arrays public TerrainQuad(List <int> tris, List <Vector3> vertices, List <Vector2> uvs, Vector3 lowerLeft, Vector3 upperRight, Tile tile, Tilemap tileset, Vector3 pos, Vector3 normal) { trisIndex = tris.Count; vertsIndex = vertices.Count; this.pos = pos; this.normal = normal; this.tile = tile; if (lowerLeft.y == 0.0f && upperRight.y == 0.0f) { invisible = true; return; } int i = vertices.Count; vertices.Add(lowerLeft); if (lowerLeft.x == upperRight.x) { vertices.Add(new Vector3(lowerLeft.x, lowerLeft.y, upperRight.z)); vertices.Add(new Vector3(lowerLeft.x, upperRight.y, lowerLeft.z)); } else if (lowerLeft.y == upperRight.y) { vertices.Add(new Vector3(lowerLeft.x, lowerLeft.y, upperRight.z)); vertices.Add(new Vector3(upperRight.x, lowerLeft.y, lowerLeft.z)); } else if (lowerLeft.z == upperRight.z) { vertices.Add(new Vector3(lowerLeft.x, upperRight.y, lowerLeft.z)); vertices.Add(new Vector3(upperRight.x, lowerLeft.y, lowerLeft.z)); } vertices.Add(upperRight); Debug.Assert(tile != null); Vector2[] spriteUVs = tile.sprite.uv; if (normal.y == 0.0f) { spriteUVs = MathHelper3D.AdjustZ(spriteUVs, tileset, lowerLeft.y, normal.x == 0.0f); } ourUVs = new Vector2[4] { spriteUVs[2], spriteUVs[0], spriteUVs[3], spriteUVs[1], }; uvs.AddRange(ourUVs); tris.Add(i); tris.Add(i + 1); tris.Add(i + 2); tris.Add(i + 1); tris.Add(i + 3); tris.Add(i + 2); }
public void UpdateTile(Tile tile, Tilemap tileset, float lowerLeftHeight) { Vector2[] spriteUVs = tile.sprite.uv; if (normal.y == 0.0f) { spriteUVs = MathHelper3D.AdjustZ(spriteUVs, tileset, lowerLeftHeight - 0.5f, normal.x == 0.0f); } ourUVs = new Vector2[4] { spriteUVs[2], spriteUVs[0], spriteUVs[3], spriteUVs[1], }; }
public void OnSceneGUI() { TacticsTerrainMesh terrain = (TacticsTerrainMesh)target; if (quads == null) { Rebuild(false); } int controlId = GUIUtility.GetControlID(FocusType.Passive); EventType typeForControl = Event.current.GetTypeForControl(controlId); switch (Event.current.button) { case 0: HandleLeftclick(typeForControl, controlId); break; case 1: HandleRightclick(typeForControl, controlId); break; } TerrainQuad quad = GetSelectedQuad(); switch (typeForControl) { case EventType.MouseMove: switch (mode) { case EditMode.None: case EditMode.Painting: if (quad != primarySelection) { CaptureSelection(quad); primarySelection = quad; SceneView.RepaintAll(); } break; } break; } MathHelper3D.DrawQuads(selectedQuads, Color.white); }
// SITEMAP GARBAGE ============== public void RegenSitemap(TacticsTerrainMesh mesh) { Vector3 v1 = new Vector3(); Vector3 v2 = new Vector3(); sitemap = new BitArray(mesh.size.x * mesh.size.y * mesh.size.x * mesh.size.y); for (int y1 = 0; y1 < mesh.size.y; y1 += 1) { for (int x1 = 0; x1 < mesh.size.x; x1 += 1) { for (int y2 = 0; y2 < mesh.size.y; y2 += 1) { for (int x2 = 0; x2 < mesh.size.x; x2 += 1) { bool res = false; int dx = x1 - x2; int dy = y1 - y2; if (dx * dx + dy * dy < 10 * 10) { v1.x = x1; v1.y = mesh.heights[y1 * mesh.size.x + x1] + 1.0f; v1.z = y1; v2.x = x2; v2.y = mesh.heights[y2 * mesh.size.x + x2] + 1.0f; v2.z = y2; res = MathHelper3D.ClearRayExists(mesh, v1, v2); } sitemap[ y2 * (mesh.size.x * mesh.size.y * mesh.size.x) + x2 * (mesh.size.x * mesh.size.y) + y1 * (mesh.size.x) + x1] = res; } } } } }
private void CaptureSelection(TerrainQuad quad) { selectedQuads = MathHelper3D.GetQuadsAroundQuad(quads, quad, selectionSize); }
private void HandleRightclick(EventType typeForControl, int controlId) { TacticsTerrainMesh terrain = (TacticsTerrainMesh)target; switch (typeForControl) { case EventType.MouseDown: if (tool != SelectionTool.Select) { TerrainQuad quad = GetSelectedQuad(); if (quad != null) { ConsumeEvent(controlId); primarySelection = quad; selectionSize = new Vector2(1.0f, 1.0f); CaptureSelection(quad); tool = SelectionTool.Paint; mode = EditMode.RlickDrag; } } break; case EventType.MouseDrag: if (mode == EditMode.RlickDrag) { ConsumeEvent(controlId); TerrainQuad quad = GetSelectedQuad(); if (quad != null && quad.normal == primarySelection.normal) { selectedQuads = MathHelper3D.GetQuadsInRect(quads, quad, primarySelection); } } break; case EventType.MouseUp: switch (mode) { case EditMode.Selected: mode = EditMode.None; break; case EditMode.RlickDrag: mode = EditMode.None; TerrainQuad quad = GetSelectedQuad(); if (quad != null && quad.normal == primarySelection.normal) { selectedQuads = MathHelper3D.GetQuadsInRect(quads, quad, primarySelection); Vector3 v1 = quad.pos; Vector3 v2 = primarySelection.pos; float x1 = Mathf.Min(v1.x, v2.x); float x2 = Mathf.Max(v1.x, v2.x); float y1 = Mathf.Min(v1.y, v2.y); float y2 = Mathf.Max(v1.y, v2.y); float z1 = Mathf.Min(v1.z, v2.z); float z2 = Mathf.Max(v1.z, v2.z); if (z1 != z2 && y1 != y2) { paletteBufferSize = new Vector2Int((int)(z2 - z1 + 1), (int)((y2 - y1 + 0.5f) * 2.0f)); paletteBuffer = new Tile[paletteBufferSize.x * paletteBufferSize.y]; for (float z = z1; z <= z2; z += 1.0f) { for (float y = y1; y <= y2; y += 0.5f) { TerrainQuad at = quads[new Vector3(v1.x, y, z)][quad.normal]; paletteBuffer[(int)(paletteBufferSize.x * (2.0f * (y - y1)) + (z - z1))] = at.tile; } } } else if (x1 != x2 && y1 != y2) { paletteBufferSize = new Vector2Int((int)(x2 - x1 + 1), (int)((y2 - y1 + 0.5f) * 2.0f)); paletteBuffer = new Tile[paletteBufferSize.x * paletteBufferSize.y]; for (float x = x1; x <= x2; x += 1.0f) { for (float y = y1; y <= y2; y += 0.5f) { TerrainQuad at = quads[new Vector3(x, y, v1.z)][quad.normal]; paletteBuffer[(int)(paletteBufferSize.x * (2.0f * (y - y1)) + (x - x1))] = at.tile; } } } else { paletteBufferSize = new Vector2Int((int)(x2 - x1 + 1), (int)(z2 - z1 + 1)); paletteBuffer = new Tile[paletteBufferSize.x * paletteBufferSize.y]; for (float x = x1; x <= x2; x += 1.0f) { for (float z = z1; z <= z2; z += 1.0f) { TerrainQuad at = quads[new Vector3(x, v1.y, z)][quad.normal]; paletteBuffer[(int)(paletteBufferSize.x * (z - z1) + (x - x1))] = at.tile; } } } selectionSize = paletteBufferSize; } break; } break; } }
private void HandleLeftclick(EventType typeForControl, int controlId) { TacticsTerrainMesh terrain = (TacticsTerrainMesh)target; switch (typeForControl) { case EventType.MouseDown: switch (tool) { case SelectionTool.HeightAdjust: if (selectedQuads.Count > 0 && selectedQuads[0].normal.y > 0.0f) { ConsumeEvent(controlId); mode = EditMode.AdjustingHeight; Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); selectedHeight = 0.0f; } break; case SelectionTool.Paint: if (selectedQuads.Count > 0) { ConsumeEvent(controlId); PaintTileIfNeeded(); mode = EditMode.Painting; paintingNormal = primarySelection.normal; } break; case SelectionTool.Select: ConsumeEvent(controlId); if (mode == EditMode.Selected) { TerrainQuad newQuad = GetSelectedQuad(); if (newQuad == null || newQuad == primarySelection) { primarySelection = null; } else { primarySelection = newQuad; CaptureSelection(primarySelection); } } mode = primarySelection == null ? EditMode.None : EditMode.Selected; break; } break; case EventType.MouseDrag: switch (mode) { case EditMode.AdjustingHeight: ConsumeEvent(controlId); selectedHeight = MathHelper3D.GetHeightAtMouse(primarySelection); break; case EditMode.Painting: ConsumeEvent(controlId); primarySelection = GetSelectedQuad(); CaptureSelection(primarySelection); PaintTileIfNeeded(); break; } break; case EventType.MouseUp: switch (mode) { case EditMode.AdjustingHeight: mode = EditMode.None; bool dirty = false; float height = MathHelper3D.GetHeightAtMouse(primarySelection); foreach (TerrainQuad quad in selectedQuads) { int x = Mathf.RoundToInt(quad.pos.x); int y = Mathf.RoundToInt(quad.pos.z); if (terrain.HeightAt(x, y) != height) { terrain.SetHeight(x, y, height); dirty = true; } } if (dirty) { Rebuild(true); } break; case EditMode.Painting: mode = EditMode.None; break; } break; case EventType.ScrollWheel: if (mode == EditMode.None && selectedQuads.Count > 0) { GUIUtility.hotControl = 0; Event.current.Use(); float maxSelection = Mathf.Max(selectionSize.x, selectionSize.y); maxSelection += -1.0f * Event.current.delta.y / 5.0f; selectionSize = new Vector2(maxSelection, maxSelection); if (Mathf.RoundToInt(selectionSize.x) < 1) { selectionSize.x = 1; } if (Mathf.RoundToInt(selectionSize.y) < 1) { selectionSize.y = 1; } CaptureSelection(primarySelection); SceneView.RepaintAll(); } break; } if (selectedHeight >= 0.0f && mode == EditMode.AdjustingHeight) { int x = Mathf.RoundToInt(primarySelection.pos.x); int y = Mathf.RoundToInt(primarySelection.pos.z); float h = terrain.HeightAt(x, y); foreach (TerrainQuad quad in selectedQuads) { float z = MathHelper3D.GetHeightAtMouse(primarySelection); for (; Mathf.Abs(z - h) > 0.1f; z += 0.5f * Mathf.Sign(h - z)) { Handles.DrawWireCube(new Vector3(quad.pos.x + 0.5f, z + 0.25f * Mathf.Sign(h - z), quad.pos.z + 0.5f), new Vector3(1.0f, 0.5f, 1.0f)); } } } }