void DrawPoint(EBWorldPainterData.Point worldPoint, TextureFills textureFill) { var point = new Vector3(worldPoint.location.x, 0.0f, worldPoint.location.y); Vector2 screenPoint = cam.WorldToViewportPoint(point) * textureSize; Rect pos = Rect.MinMaxRect(screenPoint.x - 5, (textureSize - screenPoint.y) - 5, screenPoint.x + 5, (textureSize - screenPoint.y) + 5); GUI.DrawTexture(pos, textures[(int)textureFill], ScaleMode.StretchToFill); }
void UpdateClosestPoint(EBWorldPainterData.Point point) { if (closestPoint != point) { closestPoint = point; Repaint(); } }
void DrawRegionOutline(EBWorldPainterData.Region region, Color outlineColor) { for (var i = 0; i < region.points.Count; ++i) { EBWorldPainterData.Point p0 = region.points[i]; EBWorldPainterData.Point p1 = region.points[(i + 1) % region.points.Count]; DrawLine(p0, p1, outlineColor); } }
void SetMode() { if (Event.current != null) { switch (editMode) { case EditMode.Tesselate: { if (Event.current.alt && Event.current.shift) { mode = Mode.RemovePoints; } else if (Event.current.shift) { mode = Mode.AddPoints; } else if (Event.current.command) { if (mode != Mode.SplitRegions) { lastClickedPoint = null; } mode = Mode.SplitRegions; } else if (Event.current.alt) { mode = Mode.CombineRegions; } else { mode = Mode.MovePoints; } break; } case EditMode.Visibility: { if (Event.current.shift) { mode = Mode.PaintVisible; } else { mode = Mode.PickVisibleBase; } break; } case EditMode.DataLayer: default: { mode = Mode.None; break; } } } }
private Dictionary <EBWorldPainterData.Region, Partition> PartitionMeshes(Renderer[] renderers, EBWorldPainterData worldPainterData) { if (renderers.Length == 0) { return(new Dictionary <EBWorldPainterData.Region, Partition>()); } EB.Debug.Log("Partition 1"); Dictionary <EBWorldPainterData.Region, Partition> partitions = new Dictionary <EBWorldPainterData.Region, Partition> (); for (int i = 0; i < worldPainterData.regions.Count; ++i) { Partition partition = new Partition(); partition.name = i.ToString(); partitions.Add(worldPainterData.regions[i], partition); } EB.Debug.Log("Partition 2"); foreach (Renderer renderer in renderers) { if (!RendererIsMergeable(renderer)) { continue; } EBWorldPainterData.Point p = new EBWorldPainterData.Point(new Vector2(renderer.bounds.center.x, renderer.bounds.center.z)); EBWorldPainterData.Region region; EBWorldPainterData.Region[] regions = worldPainterData.RegionsPointIsInside(p); if (regions.Length < 1) { //No regions, just add it to the first one Debug.LogError("Renderer " + renderer.name + " with bounds " + renderer.bounds + " didn't fall into any partitions"); region = worldPainterData.ClosestRegionToPoint(p); } else { region = regions[0]; } Instance instance = new Instance(); instance.renderer = renderer; partitions[region].instances.Add(instance); } EB.Debug.Log("Partition 3"); foreach (var region in worldPainterData.regions) { if (partitions[region].instances.Count == 0) { partitions.Remove(region); } } return(partitions); }
void DrawLine(EBWorldPainterData.Point worldPoint1, EBWorldPainterData.Point worldPoint2, Color color) { Vector3 p1 = new Vector3(worldPoint1.location.x, 0.0f, worldPoint1.location.y); Vector3 p2 = new Vector3(worldPoint2.location.x, 0.0f, worldPoint2.location.y); Vector2 screenPoint0 = cam.WorldToViewportPoint(p1); Vector2 screenPoint1 = cam.WorldToViewportPoint(p2); screenPoint0.y = 1.0f - screenPoint0.y; screenPoint1.y = 1.0f - screenPoint1.y; DrawingUtils.Line(screenPoint0 * textureSize, screenPoint1 * textureSize, color); }
void SwitchEditMode(EditMode em) { editMode = em; lastClickedPoint = null; lastClickedRegion = null; if (em == EditMode.BoundingBoxes) { var renderers = (MeshRenderer[])FindObjectsOfType(typeof(MeshRenderer)); worldPainterData.SetRegionBounds(renderers); } Repaint(); }
void DrawRegionBoundingBox(EBWorldPainterData.Region region, Color outlineColor) { for (var i = 0; i < region.points.Count; ++i) { EBWorldPainterData.Point p0 = new EBWorldPainterData.Point(region.bounds.min.x, region.bounds.min.z); EBWorldPainterData.Point p1 = new EBWorldPainterData.Point(region.bounds.max.x, region.bounds.min.z); EBWorldPainterData.Point p2 = new EBWorldPainterData.Point(region.bounds.max.x, region.bounds.max.z); EBWorldPainterData.Point p3 = new EBWorldPainterData.Point(region.bounds.min.x, region.bounds.max.z); DrawLine(p0, p1, outlineColor); DrawLine(p1, p2, outlineColor); DrawLine(p2, p3, outlineColor); DrawLine(p3, p0, outlineColor); } }
private void MergeSkinnedMeshes(WorldInfoInternal worldInfo, EBWorldPainterData worldPainterData) { var world = GameObject.Find("z_track"); if (world == null) { return; } Dictionary <EBWorldPainterData.Region, List <MeshFilter> > meshRegionMap = new Dictionary <EBWorldPainterData.Region, List <MeshFilter> > (); foreach (KeyValuePair <string, PieceInfo> piece in worldInfo.pieces) { GameObject prefab = GetPrefabForCode(piece.Key); if (!prefab) { Debug.LogError("No prefab for code " + piece.Key); continue; } //Deal with decision types+ MergeAdditionalCustom(piece.Key); MeshFilter[] meshFilters = GetSkinnedMeshsFor(piece.Key); if (meshFilters != null && meshFilters.Length > 0) { foreach (MeshFilter meshFilter in meshFilters) { EBWorldPainterData.Point point = new EBWorldPainterData.Point(new Vector2(meshFilter.GetComponent <Renderer>().bounds.center.x, meshFilter.GetComponent <Renderer>().bounds.center.z)); EBWorldPainterData.Region[] regions = worldPainterData.RegionsPointIsInside(point); if (regions.Length > 0) { if (!meshRegionMap.ContainsKey(regions[0])) { meshRegionMap[regions[0]] = new List <MeshFilter>(); } meshRegionMap[regions[0]].Add(meshFilter); } else { Debug.LogError("Meshfilter " + meshFilter.name + " does not fall into any region"); } } } } foreach (KeyValuePair <EBWorldPainterData.Region, List <MeshFilter> > meshRegion in meshRegionMap) { int id = meshRegion.Key.id; GameObject partition = GameObject.Find("Partition_" + id); if (partition == null) { Debug.LogError("NO Partition to parent to " + id); continue; } string savedName = _worldName + "_" + id; List <GameObject> gos = SkinnedMeshMerger.Merge(meshRegion.Value.ToArray(), savedName, _worldName); GameObject mergedBreakableMeshes = new GameObject("MergedBreakableMeshes"); mergedBreakableMeshes.transform.parent = partition.transform; foreach (GameObject g in gos) { g.layer = LayerMask.NameToLayer("environment"); g.transform.parent = mergedBreakableMeshes.transform; } } }
void OnGUI() { if (!inited) { return; } const int offset = 20; Rect textureRect = Rect.MinMaxRect(offset, offset, textureSize + offset, textureSize + offset); Rect texturSize = Rect.MinMaxRect(0, 0, textureSize, textureSize); SetMode(); //Deal with the mouse if ((Event.current != null) && Event.current.isMouse && textureRect.Contains(Event.current.mousePosition)) { Vector3 worldMousePos3 = cam.ViewportToWorldPoint(new Vector3(((float)Event.current.mousePosition.x - textureRect.x) / (float)textureSize, 1.0f - ((float)Event.current.mousePosition.y - textureRect.y) / (float)textureSize, 0.0f)); EBWorldPainterData.Point worldMousePos = new EBWorldPainterData.Point(worldMousePos3.x, worldMousePos3.z); UpdateClosestPoint(worldPainterData.ClosestPoint(worldMousePos)); UpdateClosestPoints(worldPainterData.ClosestLine(worldMousePos)); UpdateCurrentRegions(worldPainterData.RegionsPointIsInside(worldMousePos)); switch (mode) { case (Mode.None): break; case (Mode.AddPoints): { Vector2 point0 = closestPoints[0].location; Vector2 point1 = closestPoints[1].location; float distToPoint0 = Vector2.Distance(point0, worldMousePos.location); float distToPoint1 = Vector2.Distance(point1, worldMousePos.location); float t = distToPoint0 / (distToPoint0 + distToPoint1); pointToAdd = new EBWorldPainterData.Point(Vector2.Lerp(point0, point1, t)); if (Event.current.type == EventType.MouseDown) { var result = worldPainterData.InsertPoint(pointToAdd, closestPoints[0], closestPoints[1]); if (!result) { } Repaint(); } break; } case (Mode.RemovePoints): { if (Event.current.type == EventType.MouseDown) { var result = worldPainterData.RemovePoint(closestPoint); if (!result) { } Repaint(); } break; } case (Mode.MovePoints): { if (Event.current.type == EventType.MouseDown) { lastClickedPoint = closestPoint; Repaint(); } else if (Event.current.type == EventType.MouseDrag && lastClickedPoint != null) { lastClickedPoint.location = worldMousePos.location; Repaint(); } break; } case (Mode.SplitRegions): { if (Event.current.type == EventType.MouseDown) { if (lastClickedPoint == null) { lastClickedPoint = closestPoint; Repaint(); } else { EBWorldPainterData.Point nextClickedPoint = worldPainterData.ClosestPoint(worldMousePos); if (nextClickedPoint != lastClickedPoint) { EBWorldPainterData.Region[] regions = worldPainterData.RegionsContainingPoints(lastClickedPoint, nextClickedPoint); if (regions.Length == 1) { //don't want to split if the points are in more than one region, as they must be on a boundary of some sort, so splitting wouldn't make sense //TODO: don't split things that are sequential worldPainterData.SplitRegionAcrossPoints(regions[0], lastClickedPoint, nextClickedPoint); } } lastClickedPoint = null; Repaint(); } } break; } case (Mode.CombineRegions): { if (Event.current.type == EventType.MouseDown) { worldPainterData.RemoveLine(closestPoints[0], closestPoints[1]); UpdateCurrentRegions(worldPainterData.RegionsPointIsInside(worldMousePos)); Repaint(); } break; } case (Mode.PickVisibleBase): { if (Event.current.type == EventType.MouseDown) { lastClickedRegion = (currentRegions.Length > 0) ? currentRegions[0] : null; Repaint(); } break; } case (Mode.PaintVisible): { if ((lastClickedRegion != null) && (currentRegions.Length > 0) && (Event.current.type == EventType.MouseDown)) { lastClickedRegion.ToggleSeesRegion(currentRegions[0]); Repaint(); } break; } } } GUILayout.BeginHorizontal(); GUILayout.Label("Zoom", GUILayout.Width(100)); orthographicSize = GUILayout.HorizontalSlider(orthographicSize, 100.0f, 4000.0f); GUILayout.EndHorizontal(); GUI.skin = guiskin; GUILayout.BeginHorizontal(); float camPosZ = GUILayout.VerticalSlider(cam.transform.position.z, worldPainterData.WorldBounds().max.z, worldPainterData.WorldBounds().min.z); GUI.BeginGroup(textureRect); GUI.Box(texturSize, rt); GUI.EndGroup(); GUI.BeginGroup(textureRect); switch (editMode) { case EditMode.Tesselate: //Draw all the points for (int i = 0; i < worldPainterData.points.Count; ++i) { EBWorldPainterData.Point point = worldPainterData.points[i]; TextureFills tex = TextureFills.Gray; switch (mode) { case (Mode.AddPoints): if (point == closestPoint) { tex = TextureFills.Blue; } break; case (Mode.RemovePoints): if (point == closestPoint) { tex = TextureFills.Red; } break; case (Mode.MovePoints): if (point == closestPoint) { tex = TextureFills.Green; } break; case (Mode.SplitRegions): if (point == closestPoint) { tex = TextureFills.Green; } if (point == lastClickedPoint) { tex = TextureFills.Blue; } break; } DrawPoint(point, tex); } //Draw the line we may add if we are splitting regions if (mode == Mode.AddPoints) { DrawPoint(pointToAdd, TextureFills.Blue); } //Draw the line we may add if we are splitting regions if (mode == Mode.SplitRegions && lastClickedPoint != null) { DrawLine(lastClickedPoint, closestPoint, Color.blue); } //Draw all the region outlines foreach (EBWorldPainterData.Region region in worldPainterData.regions) { DrawRegionOutline(region, Color.white); } //Draw the line we may remove if we are combining regions if (mode == Mode.CombineRegions) { DrawLine(closestPoints[0], closestPoints[1], Color.red); } break; case EditMode.Visibility: //Draw all the points for (int i = 0; i < worldPainterData.points.Count; ++i) { DrawPoint(worldPainterData.points[i], TextureFills.Gray); } //Draw all the region outlines foreach (EBWorldPainterData.Region region in worldPainterData.regions) { DrawRegionOutline(region, Color.red); } //outline all the regions our current region sees, and our current region if (lastClickedRegion != null) { foreach (EBWorldPainterData.Region region in worldPainterData.regions) { if (lastClickedRegion.SeesRegion(region)) { DrawRegionOutline(region, Color.green); } } DrawRegionOutline(lastClickedRegion, new Color(0.5f, 0.5f, 1.0f)); } break; case EditMode.Hover: //Draw all the region outlines foreach (EBWorldPainterData.Region region in worldPainterData.regions) { DrawRegionOutline(region, Color.white); } //outline the one we are hovering over if (currentRegions.Length > 0) { DrawRegionOutline(currentRegions[0], new Color(0.0f, 0.5f, 0.0f)); } break; case EditMode.BoundingBoxes: //Draw all the region bounding boxes foreach (EBWorldPainterData.Region region in worldPainterData.regions) { DrawRegionBoundingBox(region, Color.white); } break; case EditMode.DataLayer: //Draw all the region outlines foreach (EBWorldPainterData.Region region in worldPainterData.regions) { DrawRegionOutline(region, Color.white); DrawDataLayer(region); } break; } GUI.EndGroup(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); float camPosX = GUILayout.HorizontalSlider(cam.transform.position.x, worldPainterData.WorldBounds().min.x, worldPainterData.WorldBounds().max.x); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); foreach (EditMode m in System.Enum.GetValues(typeof(EditMode))) { if (GUILayout.Button(m.ToString())) { SwitchEditMode(m); } } dataLayer = (EBWorldPainterData.eDATA_LAYER)EditorGUILayout.EnumPopup("Data Layer: ", dataLayer); GUILayout.EndHorizontal(); Render(camPosX, camPosZ, orthographicSize); GUI.skin = null; }