Example #1
0
    public static void Init()
    {
        origoX = Mathf.FloorToInt((float)MapLoader.minX / MapLoader.sizeDividor) - 1;
        origoY = Mathf.FloorToInt((float)MapLoader.minY / MapLoader.sizeDividor) - 1;
        endX   = Mathf.CeilToInt((float)MapLoader.maxX / MapLoader.sizeDividor) + 1;
        endY   = Mathf.CeilToInt((float)MapLoader.maxY / MapLoader.sizeDividor) + 1;

        sizeX = endX - origoX;
        sizeY = endY - origoY;

        triangles     = new List <Triangle> [sizeX, sizeY];
        sectors       = new List <Sector> [sizeX, sizeY];
        linedefs      = new List <Linedef> [sizeX, sizeY];
        monsterThings = new DoubleLinkedList <ThingController> [sizeX, sizeY];
        neutralThings = new DoubleLinkedList <ThingController> [sizeX, sizeY];
        decorThings   = new DoubleLinkedList <ThingController> [sizeX, sizeY];
        itemThings    = new DoubleLinkedList <ThingController> [sizeX, sizeY];

        for (int y = 0; y < sizeY; y++)
        {
            for (int x = 0; x < sizeX; x++)
            {
                triangles[x, y]     = new List <Triangle>();
                sectors[x, y]       = new List <Sector>();
                linedefs[x, y]      = new List <Linedef>();
                monsterThings[x, y] = new DoubleLinkedList <ThingController>();
                neutralThings[x, y] = new DoubleLinkedList <ThingController>();
                decorThings[x, y]   = new DoubleLinkedList <ThingController>();
                itemThings[x, y]    = new DoubleLinkedList <ThingController>();
            }
        }

        existenceBox = new BooleanBox(new Vec2I(origoX, origoY), new Vec2I(sizeX, sizeY));
    }
Example #2
0
    public static BooleanBox Combine(BooleanBox[] boxes)
    {
        if (boxes.Length == 0)
        {
            return(null);
        }

        if (boxes.Length == 1)
        {
            return(boxes[0]);
        }

        Vec2I origo = boxes[0].origo;
        Vec2I end   = boxes[0].end;

        for (int i = 1; i < boxes.Length; i++)
        {
            if (boxes[i] == null)
            {
                continue;
            }

            origo = Vec2I.CreateMin(origo, boxes[i].origo);
            end   = Vec2I.CreateMax(end, boxes[i].end);
        }

        BooleanBox result = new BooleanBox(origo, end - origo + Vec2I.one);

        for (int i = 0; i < boxes.Length; i++)
        {
            if (boxes[i] == null)
            {
                continue;
            }
            else
            {
                for (int y = 0; y < result.size.y; y++)
                {
                    for (int x = 0; x < result.size.x; x++)
                    {
                        if (boxes[i].GetValue(origo + new Vec2I(x, y)))
                        {
                            result.data[x, y] = true;
                        }
                    }
                }
            }
        }

        return(result);
    }
#pragma warning restore CS0108 // Member hides inherited member; missing new keyword

        private static void OnIsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is PpsWindowPaneStripItem item)
            {
                var newValue = BooleanBox.GetBool(e.NewValue);
                if (newValue)
                {
                    item.OnSelected(new RoutedEventArgs(Selector.SelectedEvent, item));
                }
                else
                {
                    item.OnUnselected(new RoutedEventArgs(Selector.UnselectedEvent, item));
                }
            }
        }         // proc OnIsSelectedChanged
 private static void ReadOnlyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
 {
     if (d is IPpsReadOnlyControl ro)
     {
         ro.IsReadOnly = BooleanBox.GetBool(e.NewValue);
     }
     else if (d is TextBox tb)
     {
         tb.IsReadOnly = BooleanBox.GetBool(e.NewValue);
     }
     else if (d is PpsDataFilterCombo ds)
     {
         ds.IsReadOnly = BooleanBox.GetBool(e.NewValue);
     }
     else if (d is PpsComboBox cb)
     {
         cb.IsReadOnly = BooleanBox.GetBool(e.NewValue);
     }
     else if (d is CheckBox c)
     {
         c.IsEnabled = !BooleanBox.GetBool(e.NewValue);
     }
 } // proc ReadOnlyPropertyChanged
Example #5
0
        /// <summary>
        /// Sets a value indicating whether to handle <see cref="SystemCommands.MinimizeWindowCommand"/>, <see cref="SystemCommands.MaximizeWindowCommand"/>, <see cref="SystemCommands.RestoreWindowCommand"/> and <see cref="SystemCommands.CloseWindowCommand"/> for the specified <see cref="Window"/>.
        /// </summary>
        /// <param name="window">The <see cref="Window"/> for which to set whether to handle commands.</param>
        /// <param name="value"><c>true</c> if to handle commands for the <paramref name="window"/>; otherwise, <c>false</c>.</param>
        public static void SetHandleWindowCommands(Window window, bool value)
        {
            Requires.NotNull(window, nameof(window));

            window.SetValue(HandleWindowCommandsProperty, BooleanBox.FromValue(value));
        }
Example #6
0
    //creates a new boolean box from two, returns false if boxes don't intersect, uses boolean operator to decide the resulting data
    public static bool Intersection(BooleanBox a, BooleanBox b, out BooleanBox result, Operation operation)
    {
        result = null;

        //no intersection
        if (a.end.AnyLowerOrEqual(b.origo) || b.origo.AnyHigherOrEqual(a.end) || b.end.AnyLowerOrEqual(a.origo) || a.origo.AnyHigherOrEqual(b.end))
        {
            return(false);
        }

        //check if other box encapsulates other or create a cross-section
        if (a.Contains(b.origo) && a.Contains(b.end))
        {
            result = new BooleanBox(b.origo, b.size);
        }
        else if (b.Contains(a.origo) && b.Contains(a.end))
        {
            result = new BooleanBox(a.origo, a.size);
        }
        else
        {
            Vec2I start = Vec2I.SelectMax(a.origo, b.origo);
            Vec2I end   = Vec2I.SelectMin(a.end, b.end);
            result = new BooleanBox(start, end - start);
        }

        //offsets
        Vec2I ao = result.origo - a.origo;
        Vec2I bo = result.origo - b.origo;

        //boolean method
        switch (operation)
        {
        default:
        case Operation.AllFalse:
            break;

        case Operation.AllTrue:
            for (int y = 0; y < result.size.y; y++)
            {
                for (int x = 0; x < result.size.x; x++)
                {
                    result.data[x, y] = true;
                }
            }
            break;

        case Operation.And:
            for (int y = 0; y < result.size.y; y++)
            {
                for (int x = 0; x < result.size.x; x++)
                {
                    result.data[x, y] = a.data[ao.x + x, ao.y + y] && b.data[bo.x + x, bo.y + y];
                }
            }
            break;

        case Operation.Or:
            for (int y = 0; y < result.size.y; y++)
            {
                for (int x = 0; x < result.size.x; x++)
                {
                    result.data[x, y] = a.data[ao.x + x, ao.y + y] || b.data[bo.x + x, bo.y + y];
                }
            }
            break;

        case Operation.Xor:
            for (int y = 0; y < result.size.y; y++)
            {
                for (int x = 0; x < result.size.x; x++)
                {
                    result.data[x, y] = a.data[ao.x + x, ao.y + y] != b.data[bo.x + x, bo.y + y];
                }
            }
            break;

        case Operation.Nor:
            for (int y = 0; y < result.size.y; y++)
            {
                for (int x = 0; x < result.size.x; x++)
                {
                    result.data[x, y] = !a.data[ao.x + x, ao.y + y] && !b.data[bo.x + x, bo.y + y];
                }
            }
            break;

        case Operation.CloneA:
            for (int y = 0; y < result.size.y; y++)
            {
                for (int x = 0; x < result.size.x; x++)
                {
                    result.data[x, y] = a.data[ao.x + x, ao.y + y];
                }
            }
            break;

        case Operation.CloneB:
            for (int y = 0; y < result.size.y; y++)
            {
                for (int x = 0; x < result.size.x; x++)
                {
                    result.data[x, y] = b.data[bo.x + x, bo.y + y];
                }
            }
            break;
        }

        return(true);
    }
Example #7
0
        /// <summary>
        /// Sets a value indicating whether to select all contents in the specified <see cref="PasswordBox"/> when it receives focus.
        /// </summary>
        /// <param name="passwordBox">The <see cref="PasswordBox"/> for which to set whether to select all contents when focus is got.</param>
        /// <param name="value"><c>true</c> if to select all contents for the <paramref name="passwordBox"/> when focus is got; otherwise, <c>false</c>.</param>
        public static void SetSelectAllOnGotFocus(PasswordBox passwordBox, bool value)
        {
            Requires.NotNull(passwordBox, nameof(passwordBox));

            passwordBox.SetValue(SelectAllOnGotFocusProperty, BooleanBox.FromValue(value));
        }
Example #8
0
            // Delegate Functions :: ThreadFunc (ThreadBase)
            protected override void ThreadFunc()
            {
                Hashtable snapshot;

                lock (Global.DB)
                    snapshot = (Hashtable)Global.DB.Songs.Clone();

                // Check for removed songs and changes
                foreach (string file in snapshot.Keys)
                {
                    FileInfo finfo = new FileInfo(file);
                    Song     song  = (Song)snapshot [file];

                    SignalRequest rq = null;

                    if (!finfo.Exists)
                    {
                        rq = Global.DB.StartRemoveSong(song);
                    }
                    else
                    {
                        long ticks = FileUtils.MTimeToTicks(song.MTime);
                        if (ticks < finfo.LastWriteTimeUtc.Ticks)
                        {
                            try {
                                Metadata metadata =
                                    new Metadata(song.Filename);

                                rq = Global.DB.StartSyncSong(song, metadata);
                            } catch {
                                try {
                                    rq = Global.DB.StartRemoveSong(song);
                                } catch (InvalidOperationException) {
                                }
                            }
                        }
                    }

                    if (rq == null)
                    {
                        continue;
                    }

                    queue.Enqueue(rq);
                }

                // Check for new songs
                foreach (string folder in Global.DB.WatchedFolders)
                {
                    DirectoryInfo dinfo = new DirectoryInfo(folder);
                    if (!dinfo.Exists)
                    {
                        continue;
                    }

                    BooleanBox canceled = new BooleanBox(false);
                    Global.DB.HandleDirectory(dinfo, queue, canceled);
                }

                thread_done = true;
            }
Example #9
0
        // Methods :: Private :: HandleDirectory
        // <summary>Directory walking</summary>
        private bool HandleDirectory
            (DirectoryInfo info, Queue queue, BooleanBox canceled_box)
        {
            // Files
            FileInfo [] finfos;
            try {
                finfos = info.GetFiles();
            } catch {
                return(true);
            }

            // Find Songs
            foreach (FileInfo finfo in finfos)
            {
                // If cancelled, get out of this mess...
                if (canceled_box.Value)
                {
                    return(false);
                }

                // If we already have the song, don't add it again
                if (this.Songs.ContainsKey(finfo.FullName))
                {
                    continue;
                }

                // Get Song
                Song song;
                try {
                    song = new Song(finfo.FullName);
                } catch {
                    continue;
                }

                // Add Song
                SignalRequest rq;
                try {
                    rq = StartAddSong(song);
                } catch (InvalidOperationException) {
                    continue;
                }

                // Queue Song
                queue.Enqueue(rq);
            }

            // Directories
            DirectoryInfo [] dinfos;

            try {
                dinfos = info.GetDirectories();
            } catch {
                return(true);
            }

            // Recurse Directories
            foreach (DirectoryInfo dinfo in dinfos)
            {
                if (HandleDirectory(dinfo, queue, canceled_box))
                {
                    continue;
                }

                return(false);
            }

            return(true);
        }
Example #10
0
        /// <summary>
        /// Sets a value indicating whether to update binding source for the <see cref="TextBox.Text"/> property of the specified <see cref="TextBox"/> when the enter key is pressed.
        /// </summary>
        /// <param name="textBox">The <see cref="TextBox"/> for which to set whether to update source of the text binding when enter key is pressed.</param>
        /// <param name="value"><c>true</c> if to update source of the text binding for the <paramref name="textBox"/> when enter key is pressed; otherwise, <c>false</c>.</param>
        public static void SetUpdateTextOnEnter(TextBox textBox, bool value)
        {
            Requires.NotNull(textBox, nameof(textBox));

            textBox.SetValue(UpdateTextOnEnterProperty, BooleanBox.FromValue(value));
        }
Example #11
0
        /// <summary>
        /// Sets a value indicating whether to select all contents in the specified <see cref="TextBoxBase"/> when it receives focus.
        /// </summary>
        /// <param name="textBox">The <see cref="TextBoxBase"/> for which to set whether to select all contents when focus is got.</param>
        /// <param name="value"><c>true</c> if to select all contents for the <paramref name="textBox"/> when focus is got; otherwise, <c>false</c>.</param>
        public static void SetSelectAllOnGotFocus(TextBoxBase textBox, bool value)
        {
            Requires.NotNull(textBox, nameof(textBox));

            textBox.SetValue(SelectAllOnGotFocusProperty, BooleanBox.FromValue(value));
        }
Example #12
0
    public static void CreateMeshes()
    {
        Transform holder = new GameObject("MapMeshes").transform;

        holder.transform.SetParent(GameManager.Instance.transform);

        //walls
        {
            int index = 0;
            foreach (Linedef l in MapLoader.linedefs)
            {
                //if (l.lineType > 0 || l.lineTag > 0)
                //Debug.Log("Line " + index + " type: " + l.lineType + " tag: " + l.lineTag);

                //add linedef to the fast lookup cache
                AxMath.CartesianLineF(l.start.Position, l.end.Position).Perform((n) =>
                {
                    int gridX = n.Data.x - TheGrid.origoX;
                    int gridY = n.Data.y - TheGrid.origoY;

                    TheGrid.linedefs[gridX, gridY].Add(l);
                    TheGrid.existenceBox.data[gridX, gridY] = true;
                });

                if (l.Back != null)
                {
                    //top part (front)
                    if (l.Front.Sector.ceilingHeight > l.Back.Sector.ceilingHeight)
                    {
                        l.TopFrontObject = CreateLineQuad
                                           (
                            l.Front,
                            l.Back.Sector.ceilingHeight,
                            l.Front.Sector.ceilingHeight + (l.Back.Sector.ceilingHeight - l.Back.Sector.minimumCeilingHeight),
                            l.Front.tHigh,
                            l.Front.offsetX,
                            (l.flags & (1 << 3)) != 0 ? l.Front.offsetY : -l.Front.offsetY,
                            (l.flags & (1 << 3)) != 0 ? 0 : 1,
                            false,
                            l.Front.Sector.brightness,
                            true,
                            "Wall_" + index + "_top_front",
                            holder
                                           );
                    }
                    //lowering ceiling (front)
                    else if (l.Front.Sector.ceilingHeight > l.Back.Sector.minimumCeilingHeight)
                    {
                        l.TopFrontObject = CreateLineQuad
                                           (
                            l.Front,
                            l.Back.Sector.ceilingHeight,
                            l.Front.Sector.ceilingHeight + (l.Back.Sector.ceilingHeight - l.Back.Sector.minimumCeilingHeight),
                            l.Front.tHigh,
                            l.Front.offsetX,
                            (l.flags & (1 << 3)) != 0 ? l.Front.offsetY : -l.Front.offsetY,
                            (l.flags & (1 << 3)) != 0 ? 0 : 1,
                            false,
                            l.Front.Sector.brightness,
                            true,
                            "Wall_" + index + "_top_front",
                            holder
                                           );
                    }

                    //top part (back)
                    if (l.Front.Sector.ceilingHeight < l.Back.Sector.ceilingHeight)
                    {
                        l.TopBackObject = CreateLineQuad
                                          (
                            l.Back,
                            l.Front.Sector.ceilingHeight,
                            l.Back.Sector.ceilingHeight,
                            l.Back.tHigh,
                            l.Back.offsetX,
                            (l.flags & (1 << 3)) != 0 ? l.Back.offsetY : l.Back.offsetY,
                            (l.flags & (1 << 3)) != 0 ? 0 : 1,
                            true,
                            l.Back.Sector.brightness,
                            true,
                            "Wall_" + index + "_top_back",
                            holder
                                          );
                    }

                    //bottom part (front)
                    if (l.Front.Sector.minimumFloorHeight < l.Back.Sector.floorHeight)
                    {
                        l.BotFrontObject = CreateLineQuad
                                           (
                            l.Front,
                            l.Front.Sector.minimumFloorHeight,
                            l.Back.Sector.floorHeight,
                            l.Front.tLow,
                            l.Front.offsetX,
                            l.Front.offsetY,
                            ((l.flags & (1 << 4)) != 0) ? 2 : 0,
                            false,
                            l.Front.Sector.brightness,
                            true,
                            "Wall_" + index + "_bot_front",
                            holder
                                           );
                    }
                    //rising floor (front)
                    else if (l.Front.Sector.maximumFloorHeight > l.Back.Sector.floorHeight && l.Front.Sector.maximumFloorHeight > l.Front.Sector.floorHeight)
                    {
                        l.BotFrontObject = CreateLineQuad
                                           (
                            l.Front,
                            l.Front.Sector.floorHeight - (l.Front.Sector.maximumFloorHeight - l.Back.Sector.floorHeight),
                            l.Front.Sector.floorHeight,
                            l.Front.tLow,
                            l.Front.offsetX,
                            l.Front.offsetY,
                            ((l.flags & (1 << 4)) != 0) ? 2 : 0,
                            false,
                            l.Front.Sector.brightness,
                            true,
                            "Wall_" + index + "_bot_front",
                            holder
                                           );
                    }

                    //bottom part (back)
                    if (l.Front.Sector.floorHeight > l.Back.Sector.minimumFloorHeight)
                    {
                        l.BotBackObject = CreateLineQuad
                                          (
                            l.Back,
                            l.Back.Sector.minimumFloorHeight,
                            l.Front.Sector.floorHeight,
                            l.Back.tLow,
                            l.Back.offsetX,
                            l.Front.offsetY,
                            ((l.flags & (1 << 4)) != 0) ? 2 : 0,
                            true,
                            l.Back.Sector.brightness,
                            true,
                            "Wall_" + index + "_bot_back",
                            holder
                                          );
                    }
                    //rising floor (back)
                    else if (l.Back.Sector.maximumFloorHeight > l.Front.Sector.floorHeight && l.Back.Sector.maximumFloorHeight > l.Back.Sector.floorHeight)
                    {
                        l.BotBackObject = CreateLineQuad
                                          (
                            l.Front,
                            l.Back.Sector.floorHeight - (l.Back.Sector.maximumFloorHeight - l.Front.Sector.floorHeight),
                            l.Back.Sector.floorHeight,
                            l.Front.tLow,
                            l.Front.offsetX,
                            l.Front.offsetY,
                            ((l.flags & (1 << 4)) != 0) ? 2 : 0,
                            false,
                            l.Front.Sector.brightness,
                            true,
                            "Wall_" + index + "_bot_front",
                            holder
                                          );
                    }

                    //middle (front)
                    if (l.Front.tMid != "-")
                    {
                        l.MidFrontObject = CreateLineQuad
                                           (
                            l.Front,
                            Mathf.Max(l.Front.Sector.floorHeight, l.Back.Sector.floorHeight),
                            Mathf.Min(l.Front.Sector.ceilingHeight, l.Back.Sector.ceilingHeight),
                            l.Front.tMid,
                            l.Front.offsetX,
                            l.Front.offsetY,
                            ((l.flags & (1 << 4)) != 0) ? 1 : 0,
                            false,
                            l.Front.Sector.brightness,
                            false,
                            "Wall_" + index + "_mid_front",
                            holder
                                           );
                    }

                    //middle (back)
                    if (l.Back.tMid != "-")
                    {
                        l.MidBackObject = CreateLineQuad
                                          (
                            l.Back,
                            Mathf.Max(l.Front.Sector.floorHeight, l.Back.Sector.floorHeight),
                            Mathf.Min(l.Front.Sector.ceilingHeight, l.Back.Sector.ceilingHeight),
                            l.Back.tMid,
                            l.Back.offsetX,
                            l.Back.offsetY,
                            ((l.flags & (1 << 4)) != 0) ? 1 : 0,
                            true,
                            l.Back.Sector.brightness,
                            false,
                            "Wall_" + index + "_mid_back",
                            holder
                                          );
                    }

                    if ((l.flags & (1 << 0)) != 0)
                    {
                        CreateInvisibleBlocker
                        (
                            l,
                            Mathf.Max(l.Front.Sector.floorHeight, l.Back.Sector.floorHeight),
                            Mathf.Min(l.Front.Sector.ceilingHeight, l.Back.Sector.ceilingHeight),
                            "Wall_" + index + "_blocker",
                            holder
                        );
                    }
                }
                else //solid wall
                {
                    l.MidFrontObject = CreateLineQuad
                                       (
                        l.Front,
                        l.Front.Sector.minimumFloorHeight,
                        l.Front.Sector.maximumCeilingHeight,
                        l.Front.tMid,
                        l.Front.offsetX,
                        l.Front.offsetY,
                        ((l.flags & (1 << 4)) != 0) ? 1 : 0,
                        false,
                        l.Front.Sector.brightness,
                        true,
                        "Wall_" + index,
                        holder
                                       );
                }

                index++;
            }
        }

        //sectors
        {
            Triangulator triangulator = new Triangulator();

            int index = 0;
            foreach (Sector s in MapLoader.sectors)
            {
                //if (s.specialType > 0 || s.tag > 0)
                //Debug.Log("Sector " + index + " type: " + s.specialType + " tag: " + s.tag);

                triangulator.Triangulate(s);

                if (Triangulator.vertices.Count == 0)
                {
                    Debug.Log("Triangulation failed for sector " + index);
                }

                //floor
                {
                    GameObject sectorObject = new GameObject("Sector_" + index + "_floor");
                    s.floorObject = sectorObject.AddComponent <SectorController>();
                    sectorObject.transform.SetParent(holder);
                    MeshRenderer mr         = sectorObject.AddComponent <MeshRenderer>();
                    MeshFilter   meshFilter = sectorObject.AddComponent <MeshFilter>();
                    Mesh         mesh       = new Mesh();
                    meshFilter.mesh = mesh;

                    if (!MaterialManager.Instance.OverridesFlat(s.floorTexture, sectorObject, mr))
                    {
                        mr.material = MaterialManager.Instance.defaultMaterial;
                    }

                    if (mr.material.mainTexture == null)
                    {
                        MaterialPropertyBlock materialProperties = new MaterialPropertyBlock();
                        materialProperties.SetTexture("_MainTex", TextureLoader.Instance.GetFlatTexture(s.floorTexture));
                        mr.SetPropertyBlock(materialProperties);
                    }

                    mesh.name = "Sector_" + index + "_floor_mesh";

                    int vc = Triangulator.vertices.Count;

                    Vector3[] vertices = new Vector3[vc];
                    Vector3[] normals  = new Vector3[vc];
                    Vector2[] uvs      = new Vector2[vc];
                    Color[]   colors   = new Color[vc];
                    int[]     indices  = new int[vc];

                    int          v      = 0;
                    int          i      = 0;
                    int          g      = 0;
                    Triangle     t      = null;
                    BooleanBox[] bboxes = new BooleanBox[Triangulator.vertices.Count / 3];
                    foreach (Vector2 p in Triangulator.vertices)
                    {
                        vertices[v] = new Vector3(p.x, s.floorHeight, p.y);
                        indices[v]  = v;
                        normals[v]  = Vector3.up;
                        uvs[v]      = new Vector2(p.x / MapLoader.flatUVdividor, 1 - (p.y / MapLoader.flatUVdividor));
                        colors[v]   = Color.white * s.brightness;

                        v++;

                        //add the triangle to the fast lookup cache
                        if (i == 0)
                        {
                            t = new Triangle();
                        }

                        t.vertices[i] = p;

                        i++;
                        if (i == 3)
                        {
                            i        = 0;
                            t.sector = s;
                            s.triangles.Add(t);

                            BooleanBox bbox = t.SelectBox;
                            if (bbox != null)
                            {
                                for (int y = 0; y < bbox.size.y; y++)
                                {
                                    for (int x = 0; x < bbox.size.x; x++)
                                    {
                                        if (bbox.data[x, y])
                                        {
                                            int gridX = bbox.origo.x - TheGrid.origoX + x;
                                            int gridY = bbox.origo.y - TheGrid.origoY + y;
                                            TheGrid.triangles[gridX, gridY].Add(t);
                                            TheGrid.existenceBox.data[gridX, gridY] = true;
                                        }
                                    }
                                }
                            }

                            bboxes[g++] = bbox;
                        }
                    }

                    //combine all triangles and add the sector to the fast lookup cache
                    BooleanBox sectorBox = BooleanBox.Combine(bboxes);
                    for (int y = 0; y < sectorBox.size.y; y++)
                    {
                        for (int x = 0; x < sectorBox.size.x; x++)
                        {
                            if (sectorBox.data[x, y])
                            {
                                int gridX = sectorBox.origo.x - TheGrid.origoX + x;
                                int gridY = sectorBox.origo.y - TheGrid.origoY + y;
                                TheGrid.sectors[gridX, gridY].Add(s);
                                TheGrid.existenceBox.data[gridX, gridY] = true;
                            }
                        }
                    }

                    mesh.vertices  = vertices;
                    mesh.triangles = indices;
                    mesh.normals   = normals;
                    mesh.uv        = uvs;
                    mesh.colors    = colors;

                    mesh.RecalculateBounds();

                    MeshCollider mc = sectorObject.AddComponent <MeshCollider>();
                    mc.sharedMesh = mesh;
                }

                //ceiling
                Triangulator.vertices.Reverse();
                {
                    GameObject sectorObject = new GameObject("Sector_" + index + "_ceiling");
                    s.ceilingObject = sectorObject;
                    sectorObject.transform.SetParent(holder);
                    MeshRenderer mr         = sectorObject.AddComponent <MeshRenderer>();
                    MeshFilter   meshFilter = sectorObject.AddComponent <MeshFilter>();
                    Mesh         mesh       = new Mesh();
                    meshFilter.mesh = mesh;
                    mesh.name       = "Sector_" + index + "_ceiling_mesh";

                    if (!MaterialManager.Instance.OverridesFlat(s.ceilingTexture, sectorObject, mr))
                    {
                        mr.material = MaterialManager.Instance.defaultMaterial;
                    }

                    if (mr.material.mainTexture == null)
                    {
                        MaterialPropertyBlock materialProperties = new MaterialPropertyBlock();
                        materialProperties.SetTexture("_MainTex", TextureLoader.Instance.GetFlatTexture(s.ceilingTexture));
                        mr.SetPropertyBlock(materialProperties);
                    }

                    int vc = Triangulator.vertices.Count;

                    Vector3[] vertices = new Vector3[vc];
                    Vector3[] normals  = new Vector3[vc];
                    Vector2[] uvs      = new Vector2[vc];
                    Color[]   colors   = new Color[vc];
                    int[]     indices  = new int[vc];

                    int v = 0;
                    foreach (Vector2 p in Triangulator.vertices)
                    {
                        vertices[v] = new Vector3(p.x, s.ceilingHeight, p.y);
                        indices[v]  = v;
                        normals[v]  = -Vector3.up;
                        uvs[v]      = new Vector2(p.x / MapLoader.flatUVdividor, 1 - (p.y / MapLoader.flatUVdividor));
                        colors[v]   = Color.white * s.brightness;
                        v++;
                    }

                    mesh.vertices  = vertices;
                    mesh.triangles = indices;
                    mesh.normals   = normals;
                    mesh.uv        = uvs;
                    mesh.colors    = colors;

                    mesh.RecalculateBounds();

                    MeshCollider mc = sectorObject.AddComponent <MeshCollider>();
                    mc.sharedMesh = mesh;
                }

                s.floorObject.sector = s;
                s.floorObject.Init();

                index++;
            }
        }
    }