public void Combine(GrassArea otherarea) { foreach (GrassSubArea subj in otherarea.subareas) { subareas.Add(subj); } otherarea.subareas.Clear(); }
public static bool Intersects(GrassArea areai, GrassArea areaj) { foreach (GrassSubArea subi in areai.subareas) { foreach (GrassSubArea subj in areaj.subareas) { if (subi.mr.bounds.Intersects(subj.mr.bounds)) { return(true); } } } return(false); }
public static bool IntersectsEx(GrassArea areai, GrassArea areaj) { foreach (GrassSubArea subi in areai.subareas) { foreach (GrassSubArea subj in areaj.subareas) { foreach (DictionaryEntry pairi in subi.bits) { if (subj.bits.ContainsKey(pairi.Key)) { return(true); } } } } return(false); }
static void ExportFun(int method, int imgwidth, int imgheight) { float fimgwidth = imgwidth; float fimgheight = imgheight; Rectangle rc = new Rectangle(0, 0, imgwidth, imgheight); System.Drawing.Bitmap img = new System.Drawing.Bitmap(imgwidth, imgheight); System.Drawing.Graphics gdi = System.Drawing.Graphics.FromImage(img); gdi.Clear(System.Drawing.Color.Black); //--------------------------------------------------------- // find renderers //--------------------------------------------------------- List <Renderer> renderers = new List <Renderer>(); GameObject[] groupgos = Selection.gameObjects; foreach (GameObject groupgo in groupgos) { Renderer[] mrs = groupgo.GetComponentsInChildren <Renderer>(); if (mrs == null) { continue; } renderers.AddRange(mrs); } //--------------------------------------------------------- // calc max bound and min bound of whole grass map //--------------------------------------------------------- Vector3 worldmin = new Vector3(9999999.0f, 9999999.0f, 9999999.0f); Vector3 worldmax = new Vector3(-9999999.0f, -9999999.0f, -9999999.0f); foreach (Renderer mr in renderers) { Bounds bound = mr.bounds; Vector3 min = bound.min; Vector3 max = bound.max; if (min.x < worldmin.x) { worldmin.x = min.x; } if (min.y < worldmin.y) { worldmin.y = min.y; } if (min.z < worldmin.z) { worldmin.z = min.z; } if (max.x > worldmax.x) { worldmax.x = max.x; } if (max.y > worldmax.y) { worldmax.y = max.y; } if (max.z > worldmax.z) { worldmax.z = max.z; } } Vector3 worldsize = worldmax - worldmin; Vector3 worldcenter = (worldmax + worldmin) * 0.5f; worldsize *= 1.1f; worldmax = worldcenter + worldsize * 0.5f; worldmin = worldcenter - worldsize * 0.5f; //--------------------------------------------------------- // generate sub area //--------------------------------------------------------- System.Drawing.Brush whitebrush = new System.Drawing.SolidBrush(System.Drawing.Color.White); List <GrassArea> areas = new List <GrassArea>(); for (int k = 0; k < renderers.Count; k++) { Mesh mesh = null; Renderer mr = renderers[k] as Renderer; if (null == mr) { continue; } if (mr.GetType() == typeof(MeshRenderer)) { MeshFilter mf = mr.GetComponent <MeshFilter>(); if (mf == null) { continue; } mesh = Application.isPlaying ? mf.mesh : mf.sharedMesh; } else { SkinnedMeshRenderer skin = mr as SkinnedMeshRenderer; mesh = skin.sharedMesh; } if (mesh == null) { continue; } Transform tran = renderers[k].transform; List <PointF> nodes = new List <PointF>(); for (int i = 0; i < mesh.vertexCount; i++) { Vector3 vertex = mesh.vertices[i]; Vector3 pos = tran.TransformPoint(vertex); PointF point = new PointF(); point.X = (pos.x - worldmin.x) / worldsize.x * fimgwidth; point.Y = fimgheight - 1.0f - (pos.z - worldmin.z) / worldsize.z * fimgheight; nodes.Add(point); } ConvexAogrithm ca = new ConvexAogrithm(nodes); Stack <PointF> p_nodes = ca.GetResult(); PointF[] convex = p_nodes.ToArray(); gdi.Clear(System.Drawing.Color.Black); gdi.FillPolygon(whitebrush, convex); gdi.Flush(); System.Drawing.Imaging.BitmapData bmp = img.LockBits(rc, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); int stride = imgwidth * 4; byte[] data = new byte[imgwidth * imgheight * 4]; Marshal.Copy(bmp.Scan0, data, 0, imgwidth * imgheight * 4); img.UnlockBits(bmp); Hashtable bits = new Hashtable(); for (int y = 0; y < imgheight; y++) { for (int x = 0; x < imgwidth; x++) { int g = data[y * stride + x * 4 + 1]; if (g != 0) { bits[y * imgwidth + x] = g; } } } GrassSubArea subarea = new GrassSubArea(); subarea.mr = renderers[k]; subarea.convex = convex; subarea.bits = bits; GrassArea area = new GrassArea(); area.subareas.Add(subarea); areas.Add(area); float fProgress = (float)k / (float)renderers.Count; EditorUtility.DisplayProgressBar("Export Grass Map", "Generate Area...", fProgress); } whitebrush.Dispose(); whitebrush = null; //--------------------------------------------------------- // intersects and combine //--------------------------------------------------------- int count = 0; for (int pass = 0; pass < 10; pass++) { for (int j = 0; j < areas.Count; j++) { GrassArea aj = areas[j]; for (int i = 0; i < j; i++) { GrassArea ai = areas[i]; if (GrassArea.IntersectsEx(ai, aj)) { aj.Combine(ai); } } count++; float fProgress = (float)count / (10.0f * areas.Count); EditorUtility.DisplayProgressBar("Export Grass Map", "IntersectsEx...", fProgress); } } EditorUtility.ClearProgressBar(); //--------------------------------------------------------- // export //--------------------------------------------------------- string imgpath = EditorUtility.SaveFilePanel("grass map", Application.dataPath, "grassmap", "jpg"); string csvpath = ""; if (imgpath.Length > 3) { csvpath = imgpath.Substring(0, imgpath.Length - 3) + "csv"; } StreamWriter sw = null; if (csvpath.Length > 3) { sw = new StreamWriter(csvpath, false); } if (sw != null) { // sw.WriteLine("?,undefied,undefied,undefied,undefied,undefied,undefied,undefied,undefied,undefied,undefied"); // sw.WriteLine("?,undefied,undefied,undefied,undefied,undefied,undefied,undefied,undefied,undefied,undefied"); // sw.WriteLine("#,minx,minz,maxx,maxz"); // sw.WriteLine("world" + "," + worldmin.x.ToString() + "," + worldmin.z.ToString() + "," + worldmax.x.ToString() + "," + worldmax.z.ToString()); // sw.WriteLine("#,area,subarea,colorr,colorg,colorb,minx,minz,maxx,maxz,convex"); { sw.WriteLine("area,subarea,colorr,colorg,colorb,bmp_minx,bmp_minz,bmp_maxx,bmp_maxz,minx,minz,maxx,maxz,convex"); sw.WriteLine("int,int,int,int,int,float,float,float,float,float,float,float,float,string"); } } gdi.Clear(System.Drawing.Color.Black); int areacount = 0; foreach (GrassArea area in areas) { if (area.subareas.Count <= 0) { continue; } int colorindex = areacount + 1; int b = colorindex % 4; int g = (colorindex / 4) % 4; int r = colorindex / (4 * 4); r *= 64; g *= 64; b *= 64; if (r > 255) { r = 255; } if (g > 255) { g = 255; } if (b > 255) { b = 255; } System.Drawing.Color c = System.Drawing.Color.FromArgb(r, g, b); System.Drawing.Brush brush = new System.Drawing.SolidBrush(c); for (int k = 0; k < area.subareas.Count; k++) { GrassSubArea subarea = area.subareas[k]; if (method == 1) { gdi.FillPolygon(brush, subarea.convex); } else if (method == 2) { MeshFilter mf = subarea.mr.GetComponent <MeshFilter>(); if (mf == null) { continue; } Mesh mesh = Application.isPlaying ? mf.mesh : mf.sharedMesh; if (mesh == null) { continue; } Transform tran = mf.transform; for (int j = 0; j < mesh.triangles.Length / 3; j++) { int[] indices = new int[3]; for (int i = 0; i < 3; i++) { indices[i] = mesh.triangles[j * 3 + i]; } Vector3[] vertices = new Vector3[3]; for (int i = 0; i < 3; i++) { vertices[i] = mesh.vertices[indices[i]]; } Vector3[] positions = new Vector3[3]; for (int i = 0; i < 3; i++) { positions[i] = tran.TransformPoint(vertices[i]); } System.Drawing.PointF[] points = new System.Drawing.PointF[3]; for (int i = 0; i < 3; i++) { points[i].X = (positions[i].x - worldmin.x) / worldsize.x * fimgwidth; points[i].Y = fimgheight - 1.0f - (positions[i].z - worldmin.z) / worldsize.z * fimgheight; } gdi.FillPolygon(brush, points); } } else { Bounds bound = subarea.mr.bounds; Vector3 min = bound.min; Vector3 max = bound.max; float px = (min.x - worldmin.x) / worldsize.x * (float)imgwidth; float py = 511.0f - (min.z - worldmin.z) / worldsize.z * (float)imgheight; float pw = (max.x - min.x) / worldsize.x * (float)imgwidth; float ph = (max.z - min.z) / worldsize.z * (float)imgheight; py -= ph; gdi.FillRectangle(brush, px, py, pw, ph); } if (sw != null) { string convexstr = ""; foreach (PointF pt in subarea.convex) { convexstr += "{" + pt.X.ToString() + "|" + pt.Y.ToString() + "};"; } // sw.WriteLine("area" + "," // + areacount.ToString() + "," // + k.ToString() + "," // + r.ToString() + "," // + g.ToString() + "," // + b.ToString() + "," // + subarea.mr.bounds.min.x.ToString() + "," // + subarea.mr.bounds.min.z.ToString() + "," // + subarea.mr.bounds.max.x.ToString() + "," // + subarea.mr.bounds.max.z.ToString() + "," // + convexstr // ); { sw.WriteLine(areacount.ToString() + "," + k.ToString() + "," + r.ToString() + "," + g.ToString() + "," + b.ToString() + "," + worldmin.x.ToString() + "," + worldmin.z.ToString() + "," + worldmax.x.ToString() + "," + worldmax.z.ToString() + "," + subarea.mr.bounds.min.x.ToString() + "," + subarea.mr.bounds.min.z.ToString() + "," + subarea.mr.bounds.max.x.ToString() + "," + subarea.mr.bounds.max.z.ToString() + "," + convexstr ); } } } brush.Dispose(); brush = null; areacount++; } gdi.Flush(); if (imgpath.Length > 3) { img.Save(imgpath); } if (sw != null) { sw.Close(); sw.Dispose(); sw = null; } gdi.Dispose(); gdi = null; img.Dispose(); img = null; if (imgpath.Length > 3) { Debug.Log("generate grass map ok:" + imgpath); System.Diagnostics.Process.Start(imgpath, ""); } if (csvpath.Length > 3) { Debug.Log("generate grass list ok:" + csvpath); //System.Diagnostics.Process.Start(csvpath, ""); } }
// Start is called before the first frame update void Awake() { for (int i = 0; i < Setting.areaDeckCount[Setting.AreaType.Ant]; i++) { areaList.Add(new AntArea()); } for (int i = 0; i < Setting.areaDeckCount[Setting.AreaType.Rotate]; i++) { areaList.Add(new RotateArea()); } for (int i = 0; i < Setting.areaDeckCount[Setting.AreaType.Exchange]; i++) { areaList.Add(new ExchangeArea()); } for (int i = 0; i < Setting.areaDeckCount[Setting.AreaType.EPresent]; i++) { areaList.Add(new EpresentArea()); } for (int i = 0; i < Setting.areaDeckCount[Setting.AreaType.Gap]; i++) { areaList.Add(new GapArea()); } for (int i = 0; i < Setting.areaDeckCount[Setting.AreaType.Grass]; i++) { areaList.Add(new GrassArea()); } for (int i = Setting.MIN_AREA; i <= Setting.MAX_AREA; i++) { for (int j = Setting.MIN_AREA; j <= Setting.MAX_AREA; j++) { Vector3Int key = new Vector3Int(i, j, 0); if (tilemap.HasTile(key)) { lights[key] = Instantiate(lightPrefab, GetWorldPosition(key), Quaternion.identity, transform); highlights[key] = Instantiate(highlightPrefab, GetWorldPosition(key), Quaternion.identity, transform); lights[key].SetActive(false); highlights[key].SetActive(false); if (key == Setting.houseStartIndex) { areas[key] = new HouseArea(); areas[key].Trigger(key); areas[key].ShowForward(tilemap, key); continue; } else if (key == Setting.girlStartIndex) { areas[key] = new Way1_2_3_4_5_6Area(TileManager.Instance.way1_2_3_4_5_6); areas[key].ShowForward(tilemap, key); continue; } else if (key == Setting.antStartIndex) { areas[key] = new GrassArea(); areas[key].ShowForward(tilemap, key); continue; } int id = UnityEngine.Random.Range(0, areaList.Count); var data = areaList[id]; areaList.RemoveAt(id); areas[key] = data; } } } if (areaList.Count != 0) { Debug.LogError(ToString() + "Area count error" + areaList.Count); } }