Example #1
0
        //static Color white = Color.white;
        // その場所が空き地かどうか調べる
        static public bool IsEmptyField(Vector3 pos, Liver.Entity.AreaMap areaMap, Vector3 offset)
        {
            // 画像上の位置
            var tpos = pos - offset;
            //Debug.Log($"{pos.x}, {pos.z} -> {tpos.x}, {tpos.z}");
            int x = (int)tpos.x;
            int y = (int)tpos.z;

            if (!areaMap.Contain(x, y))
            {
                return(false);
            }

            var color = areaMap.GetPixel(x, y);

            return(!(color.g > 0));
            //return ExtendedColor.FastEqual(ref color, ref white);
        }
Example #2
0
        public GameObject FenceRight; // 右側のみ

        public IEnumerator Process(RoadInfo roadInfo, GridArea gridArea, Liver.Entity.AreaMap areaMap)
        {
            if (FenceAll == null || FenceLeft == null || FenceRight == null)
            {
                yield break;
            }

            Debug.Log("FenceLayouter.Process");
            // ピクセルを配列でゲット
            var   num             = (int)LocationDeterminer.GridSizeKilometer;
            var   offset          = new Vector3(num * -0.5f, 0, num * -0.5f);
            var   dummy           = Instantiate <GameObject>(this.FenceAll).transform;
            var   left            = dummy.Find("left");
            var   right           = dummy.Find("right");
            var   vFront          = new Vector3(0, 0, -2);
            var   vBack           = new Vector3(0, 0, 2);
            var   half            = Map.LocationDeterminer.GridSizeKilometer * 0.5f;
            float goNextFrameTime = Time.realtimeSinceStartup + 0.03f;

            foreach (var road in roadInfo.Roads)
            {
                // 道の長さを計算
                float l = road.TotalLength;

                // 交差点の前後5mには置かない
                if (l < (3 + 6 + 3) * 2)
                {
                    continue;
                }

                float d = 3 + 6 + 3;

                while (l > (d + 3 + 6 + 3))
                {
                    if (Random.Range(0.0f, 1.0f) < 0.5f)
                    {
                        var p = RoadInfo.CalcPosition(road, d);
                        var v = RoadInfo.CalcVector(road, d);

                        // 3kmグリッド内か判定
                        if (Mathf.Abs(p.x) > half || Mathf.Abs(p.z) > half)
                        {
                            d += 8.0f;
                            continue;
                        }

                        if (RoadInfo.CheckVertex(road, d, 16, 0.99f))
                        {
                            var q = Quaternion.LookRotation(v); // 向きを計算する
                            // 計算のため、ダミーの座標と向きを設定する
                            dummy.localPosition = p;
                            dummy.localRotation = q;
                            byte bit = 0;

                            // テクスチャ画像上での色を調査
                            if (IsEmptyField(left.position, areaMap, offset) &&
                                IsEmptyField(left.position + q * vFront, areaMap, offset) &&
                                IsEmptyField(left.position + q * vBack, areaMap, offset))
                            {
                                bit |= 1 << 0;
                            }                                                                                   // 左

                            if (IsEmptyField(right.position, areaMap, offset) &&
                                IsEmptyField(right.position + q * vFront, areaMap, offset) &&
                                IsEmptyField(right.position + q * vBack, areaMap, offset))
                            {
                                bit |= 1 << 1;
                            }                                                                                    // 右

                            switch (bit)
                            {
                            // 左のみ
                            case 1:
                                gridArea.Component <PoolEnliven>(p).Add(this.FenceLeft, p, q);
                                break;

                            // 右のみ
                            case 2:
                                gridArea.Component <PoolEnliven>(p).Add(this.FenceRight, p, q);
                                break;

                            // 両方
                            case 3:
                                gridArea.Component <PoolEnliven>(p).Add(this.FenceAll, p, q);
                                break;
                            }
                        }
                    }

                    d += 8.0f;
                }

                // 一定時間ごとにyield
                if (Time.realtimeSinceStartup > goNextFrameTime)
                {
                    yield return(null);

                    goNextFrameTime = Time.realtimeSinceStartup + 0.03f;
                }
            }

            Destroy(dummy.gameObject);
            //texture.SetPixels32(colors);
        }
Example #3
0
        public int EmptyAreaSize(Liver.Entity.AreaMap areaMap, int x, int y, int step, int max)
        {
            int current = step;

            while (current < max)
            {
                // 四方向調べる
                // NOTE 建物が四角いので4端を調査
                if (!areaMap.Contain(x - current, y - current))
                {
                    return(current - step);
                }

                if (!areaMap.Contain(x - current, y + current))
                {
                    return(current - step);
                }

                if (!areaMap.Contain(x + current, y - current))
                {
                    return(current - step);
                }

                if (!areaMap.Contain(x + current, y + current))
                {
                    return(current - step);
                }

                var leftup = areaMap.GetPixel(x - current, y - current);

                if ((leftup.r > 0))
                {
                    return(current - step);
                }

                //if (!ExtendedColor.FastEqual(ref up, ref white)) return current - step;
                var leftdown = areaMap.GetPixel(x - current, y + current);

                if ((leftdown.r > 0))
                {
                    return(current - step);
                }

                //if (!ExtendedColor.FastEqual(ref down, ref white)) return current - step;
                var rightup = areaMap.GetPixel(x + current, y - current);

                if ((rightup.r > 0))
                {
                    return(current - step);
                }

                //if (!ExtendedColor.FastEqual(ref left, ref white)) return current - step;
                var rightdown = areaMap.GetPixel(x + current, y + current);

                if ((rightdown.r > 0))
                {
                    return(current - step);
                }

                //if (!ExtendedColor.FastEqual(ref right, ref white)) return current - step;
                current += step;
            }

            return(max);
        }
Example #4
0
        // 生成
        public IEnumerator Process(GridArea gridArea, Liver.Entity.AreaMap areaMap)
        {
            Debug.Log("EnlivenLayouter.Process");

            if (enlivens.Length == 0)
            {
                yield break;
            }

            // テキストから生成
            var enliven = Enliven.Load();

            yield return(null);

            var   num = (int)LocationDeterminer.GridSizeKilometer;
            var   offset = new Vector3(num * -0.5f, 0, num * -0.5f);
            int   x, y, size;
            float goNextFrameTime = Time.realtimeSinceStartup + 0.03f;

            for (int i = 0; i < enliven.Count; i++)
            {
                enliven.Unpack(i, out x, out y, out size);
                var color = areaMap.GetPixel(x, y);

                if (color.r > 0)
                {
                    continue;
                }

                //if (!ExtendedColor.FastEqual(ref color, ref white)) continue;
                var emptySize = Mathf.Max(1, EmptyAreaSize(areaMap, x, y, 1, Mathf.Min(size, maxSize)));
#if false
                // 空きスペース以下のプレハブをランダムで抽選する
                var count = System.Array.FindLastIndex(enlivens, (e) =>
                {
                    return(e.size <= emptySize);
                });
                var prefab = enlivens[Random.Range(0, count + 1)].prefab;
#else
                GameObject prefab = null;
                // なるべく大きいオブジェクトを配置する
                // MEMO : サイズ1以上のものが複数がある場合、後ろのほうが抽選されます。(現時点対応必要ないため放置します。
                int count = enlivens.Length - 1;

                for (int j = enlivens.Length - 1; j >= 0; j--)
                {
                    if (enlivens[j].size <= emptySize)
                    {
                        count = j;
                        break;
                    }
                }

                if (enlivens[count].size != 1)
                {
                    prefab = enlivens[count].prefab;
                }
                else
                {
                    prefab = enlivens[Random.Range(0, count + 1)].prefab;
                }
#endif
                var p = new Vector3(x + offset.x, 0 + offset.y, y + offset.z);
                var c = gridArea.Component <PoolEnliven>(p);
                c.Add(prefab, p);

                // 一定時間ごとにyield
                if (Time.realtimeSinceStartup > goNextFrameTime)
                {
                    yield return(null);

                    goNextFrameTime = Time.realtimeSinceStartup + 0.03f;
                }
            }
        }