Пример #1
0
        public Node( Node original )
        {
            //location = original.location;
            level = original.level;
            data = original.data;

            if ( original.IsLeaf() )
                BecomeLeaf();
            else
                BecomeBranch();
        }
Пример #2
0
        private Node BuildTree( int x, int y, int factor )
        {
            // factor 0 = 1 pixel, so don't do advanced searching as it's useless.
            int size = 1 << factor;
            int topleft = source.Memory[x,y].Color << 16;
            int topright = source.Memory[x+size,y].Color << 16;
            int bottomleft = source.Memory[x,y+size].Color << 16;
            int bottomright = source.Memory[x+size,y+size].Color << 16;

            int leftystep = (bottomleft-topleft)/size;
            int rightystep = (bottomright-topright)/size;
            int blockowner = source[x,y].ID;

            // Walk over the blocks contents, and see if it is "uniform" or not.
            // if it isn't, divide it into 4 subblocks and do the subprocessing of each block.
            for ( int cy=0, leftcolor=topleft, rightcolor=topright;
                cy<size;
                ++cy, leftcolor+=leftystep, rightcolor+=rightystep ) {
                int xstep = (rightcolor-leftcolor) / size;

                for ( int cx=0, color = leftcolor; cx<size; ++cx, color+=xstep ) {
                    Pixel mem = source[x+cx,y+cy];
                    if ( mem.ID != blockowner || mem.IsBorder() || Math.Abs( mem.Color - ((color + 0x008000)>>16) ) >= thresholds[factor] ) {
                        // Need to create a branch
                        Node node = new Node( false );

                        if ( --factor == 0 ) {
                            node.BottomRightChild = new Node( source[x+1,y+1] );
                            node.BottomLeftChild = new Node( source[x,y+1] );
                            node.TopRightChild = new Node( source[x+1,y] );
                            node.TopLeftChild = new Node( source[x,y] );
                        }
                        else {
                            size >>= 1; // Half the size
                            node.BottomRightChild = BuildTree( x+size, y+size, factor );
                            node.BottomLeftChild = BuildTree( x, y+size, factor );
                            node.TopRightChild = BuildTree( x+size, y, factor );
                            node.TopLeftChild = BuildTree( x, y, factor );
                        }

                        return node;
                    }
                }
            }

            // This block is "uniform" so create a leaf...
            return new Node( source[x,y] );
        }
Пример #3
0
        protected override void OnVisitNode( Node node, int x, int y )
        {
            Bitmap vis = null;
            if ( node.IsBranch() && node.Level > 1 ) {
                // combine 4 images into a larger one
                Bitmap tl = (Bitmap)imagestack.Pop();
                Bitmap tr = (Bitmap)imagestack.Pop();
                Bitmap bl = (Bitmap)imagestack.Pop();
                Bitmap br = (Bitmap)imagestack.Pop();

                int width = bl.Width + br.Width;
                if ( tl.Width + tr.Width > width ) width = tl.Width + tr.Width;

                int height = tl.Height + bl.Height;
                if ( tr.Height + br.Height > height ) height = tr.Height + br.Height;

                vis = new Bitmap( width + VisPadding, height + VisPadding );
                using ( Graphics g = Graphics.FromImage( vis ) ) {
                    g.DrawImageUnscaled( tl, 0, 0 );
                    g.DrawImageUnscaled( tr, vis.Width-tr.Width, 0 );
                    g.DrawImageUnscaled( bl, 0, vis.Height-bl.Height );
                    g.DrawImageUnscaled( br, vis.Width-br.Width, vis.Height-br.Height );
                }
            }
            else if ( node.IsBranch() ) {
                // Display 4 leaves on pixel level
                vis = new Bitmap( VisSize*2 + VisPadding, VisSize*2 + VisPadding, PixelFormat.Format32bppArgb );
                using ( Graphics g = Graphics.FromImage( vis ) ) {
                    g.DrawLine( Pens.Black, VisSize, VisSize, vis.Width-VisSize, vis.Height-VisSize );
                    g.DrawLine( Pens.Black, vis.Width-VisSize, VisSize, VisSize, vis.Height-VisSize );
                    DrawNode( node.BottomRightChild, g,  vis.Width-VisSize, vis.Height-VisSize );
                    DrawNode( node.BottomLeftChild, g, 0, vis.Height-VisSize );
                    DrawNode( node.TopRightChild, g,  vis.Width-VisSize, 0 );
                    DrawNode( node.TopLeftChild, g, 0, 0 );
                }
            }
            else { // Display a leaf above pixel level
                vis = new Bitmap( VisSize << node.Level, VisSize << node.Level, PixelFormat.Format32bppArgb );
                using ( Graphics g = Graphics.FromImage( vis ) ) {
                    DrawNode( node, g, 0, 0 );
                }
            }

            imagestack.Push( vis );
        }
Пример #4
0
        private static Node DecompressTree( byte[] data, ref int index )
        {
            // Copy the tree into a bit array
            // We know there can be at most 43 bytes of data (1024 pixels or 668 nodes), so we copy those
            // first and resize it to the proper size later.
            int srcsize = index+45 < data.Length ? 45 : data.Length-index;
            byte[] srcdata = new byte[srcsize];
            Array.Copy( data, index, srcdata, 0, srcsize );
            BitArray srctree = new BitArray( srcdata );
            srcdata = null;

            int nodeIndex = 0;
            Node tree = new Node(true);
            ConvertBitTree( 5, srctree, ref nodeIndex, tree );
            index += (int)((nodeIndex+7) / 8); // Set proper data index
            //index += (int)(nodeIndex / 8); // Set proper data index

            return tree;
        }
Пример #5
0
 public void Erase( )
 {
     tree = new Node( false );
     tree.BottomRightChild = new Node( Pixel.Empty );
     tree.BottomLeftChild = new Node( Pixel.Empty );
     tree.TopRightChild = new Node( Pixel.Empty );
     tree.TopLeftChild = new Node( Pixel.Empty );
 }
Пример #6
0
        private static void ConvertBitTree( int level, BitArray srctree, ref int nodeIndex, Node parent )
        {
            // Get flag, and advance node pointer
            bool flag = srctree[nodeIndex++];

            if ( flag && level > 1 ) {
                parent.CreateBranches();

                ConvertBitTree( level - 1, srctree, ref nodeIndex, parent.BottomRightChild );
                ConvertBitTree( level - 1, srctree, ref nodeIndex, parent.BottomLeftChild );
                ConvertBitTree( level - 1, srctree, ref nodeIndex, parent.TopRightChild );
                ConvertBitTree( level - 1, srctree, ref nodeIndex, parent.TopLeftChild );
            }
            else {
                if ( flag ) {
                    parent.CreateLeaves();
                }
                else {
                    parent.BecomeLeaf();
                }
            }
        }
Пример #7
0
        public void Decompress( CompressedBlock compressed, AdjacencyTable adjacent )
        {
            int index = 0;

            // Decompress the ID table from the data stream
            Pixel[] owners;
            int ownercount = DecompressIdTable( compressed.Data, ref index, adjacent, out owners );

            // Decompress the tree from the data stream
            tree = DecompressTree( compressed.Data, ref index );
            int leafcount = tree.CalcLeafCount();
            // Create the leaf array
            Pixel[] leafs = new Pixel[leafcount + (leafcount % 8 == 0 ? 0 : 8-(leafcount % 8))];

            // Decompress the ownership table next
            DecompressOwnership( compressed.Data, ref index, leafs, leafcount, owners, ownercount );

            // Finally, read the color data, which contains the "color" data for each leaf.
            DecompressColorInfo( compressed.Data, ref index, leafs, leafcount );

            // Assign the leaf data to the nodes
            int leafIndex = 0;
            PopulateNode( tree, leafs, ref leafIndex );
        }
Пример #8
0
 public MapBlock( Node root )
 {
     tree = root;
 }
Пример #9
0
        protected void WalkTreeFull( Node node, int x, int y )
        {
            if ( node == null ) return;
            int size = ((1 << node.Level) >> 1);
            Node.ChildMaskLocation oldmask = node.ChildMask;

            if ( node.IsBranch() && node.Level > stopAtLevel ) {
                if ( visitBranches ) OnVisitNode( node, x, y );

                if ( node.IsBranch() ) {
                    WalkTreeFull( node.BottomRightChild, x+size, y+size );
                    WalkTreeFull( node.BottomLeftChild, x, y+size );
                    WalkTreeFull( node.TopRightChild, x+size, y );
                    WalkTreeFull( node.TopLeftChild, x, y );
                }
            }
            else {
                OnVisitNode( node, x, y );

                // OnVisitNode might have changed the node (leaf<->branch), so have to recheck
                if ( node.ChildMask != oldmask && node.IsBranch() ) {
                    WalkTreeFull( node.BottomRightChild, x+size, y+size );
                    WalkTreeFull( node.BottomLeftChild, x, y+size );
                    WalkTreeFull( node.TopRightChild, x+size, y );
                    WalkTreeFull( node.TopLeftChild, x, y );
                }
            }
        }
Пример #10
0
        public static MapBlock Combine( MapBlock[,] matrix )
        {
            Node root = new Node( false );

            // Create 4 children
            root.BottomRightChild = new Node( false );
            root.BottomLeftChild = new Node( false );
            root.TopRightChild = new Node( false );
            root.TopLeftChild  = new Node( false );

            // Add items to children
            root.BottomRightChild.BottomRightChild = matrix[3,3].Tree.Clone();
            root.BottomRightChild.BottomLeftChild = matrix[2,3].Tree.Clone();
            root.BottomRightChild.TopRightChild = matrix[3,2].Tree.Clone();
            root.BottomRightChild.TopLeftChild = matrix[2,2].Tree.Clone();

            root.BottomLeftChild.BottomRightChild = matrix[1,3].Tree.Clone();
            root.BottomLeftChild.BottomLeftChild = matrix[0,3].Tree.Clone();
            root.BottomLeftChild.TopRightChild = matrix[1,2].Tree.Clone();
            root.BottomLeftChild.TopLeftChild = matrix[0,2].Tree.Clone();

            root.TopRightChild.BottomRightChild = matrix[3,1].Tree.Clone();
            root.TopRightChild.BottomLeftChild = matrix[2,1].Tree.Clone();
            root.TopRightChild.TopRightChild = matrix[3,0].Tree.Clone();
            root.TopRightChild.TopLeftChild = matrix[2,0].Tree.Clone();

            root.TopLeftChild.BottomRightChild = matrix[1,1].Tree.Clone();
            root.TopLeftChild.BottomLeftChild = matrix[0,1].Tree.Clone();
            root.TopLeftChild.TopRightChild = matrix[1,0].Tree.Clone();
            root.TopLeftChild.TopLeftChild = matrix[0,0].Tree.Clone();

            root.Level = matrix[3,3].Tree.Level+2;

            // Use for new block
            MapBlock result = new MapBlock( root );

            // Clip the tree
            result.WalkTree( new MapBlockHandling.TreeClipperDeep( ) );
            result.tree.Level = 5;

            // Optimise the tee
            result.WalkTree( new MapBlockHandling.TreeOptimiser( true ) );

            return result;
        }
Пример #11
0
 private void PaintNode(  Node node, int x, int y )
 {
     int v = 0xFF - (node.Data.Color << 2);
     SolidBrush brush;
     if ( node.Data.IsBorder() )
         brush = new SolidBrush( Color.FromArgb( 0xFF, v, v ) );
     else
         brush = new SolidBrush( Color.FromArgb( v, v, v ) );
     paintgraphics.FillRectangle( brush, x*20 + 1, y*20 + 1, 20*(1<<node.Level)-2, 20*(1<<node.Level)-2 );
     brush.Dispose();
     paintgraphics.DrawString( node.Data.ID.ToString(), lblFont.Font, node.Data.Color > 32 ? Brushes.White : Brushes.Black, x*20 + 2, y*20 + 2 );
     //if ( chkDisplayColors.Checked )
         paintgraphics.DrawString( node.Data.Color.ToString(), lblFont.Font, node.Data.Color > 32 ? Brushes.Yellow : Brushes.Blue, x*20 + 2, y*20 + 10 );
     //else
     //	paintgraphics.DrawString( node.Data.Full.ToString(), lblFont.Font, node.Data.Color > 32 ? Brushes.White : Brushes.Black, x*20 + 2, y*20 + 10 );
 }
Пример #12
0
 protected abstract void OnVisitNode( Node node, int x, int y );
Пример #13
0
        public void CreateLeaves()
        {
            BecomeBranch();

            children[0] = new Node( true, level-1 );
            children[1] = new Node( true, level-1 );
            children[2] = new Node( true, level-1 );
            children[3] = new Node( true, level-1 );
        }
Пример #14
0
 private void PopulateNode( Node node, Pixel[] leafs, ref int index )
 {
     if ( !node.IsLeaf() ) {
         PopulateNode( node.BottomRightChild, leafs, ref index );
         PopulateNode( node.BottomLeftChild, leafs, ref index );
         PopulateNode( node.TopRightChild, leafs, ref index );
         PopulateNode( node.TopLeftChild, leafs, ref index );
     }
     else {
         node.Data = leafs[index++];
     }
 }
Пример #15
0
        public void CreateBranches()
        {
            BecomeBranch();

            children[0] = new Node( false, level-1 );
            children[1] = new Node( false, level-1 );
            children[2] = new Node( false, level-1 );
            children[3] = new Node( false, level-1 );
        }
Пример #16
0
        public Node Clone()
        {
            Node result = new Node( IsLeaf(), level );
            result.data = data;
            if ( IsBranch() ) {
                result.children[0] = children[0].Clone();
                result.children[1] = children[1].Clone();
                result.children[2] = children[2].Clone();
                result.children[3] = children[3].Clone();
            }

            return result;
        }
Пример #17
0
        private void RightWalker( Node node, int x, int y )
        {
            x += Lightmap.BlockSize;
            if ( node.IsBranch() ) {
                shadow[x,y+1] = node.BottomLeftChild.Data.Color;
                shadow[x,y] = node.TopLeftChild.Data.Color;
            }
            else {
                int size = 1 << node.Level;
                int topleft = node.Data.Color << 16;
                int bottomleft = (shadow[x, y+size]) << 16;

                // Do the interpolation
                int delta = (bottomleft - topleft) >> node.Level;
                int color = topleft;

                for ( int a = 0; a<size; a++ ) { // Loop horizontally
                    shadow[x, y+a] = (byte)(color>>16);
                    color += delta;
                }
            }
        }
Пример #18
0
        private void DrawWalker( Node node, int x, int y )
        {
            int level = node.Level;
            x += sx;
            y += sy;

            if ( node.IsBranch() ) {
                shadow[x-sx+1,y-sy+1] = (memory[(x+1),(y+1)] = node.BottomRightChild.Data).Color;
                shadow[x-sx,y-sy+1] = (memory[x,(y+1)] = node.BottomLeftChild.Data).Color;
                shadow[x-sx+1,y-sy] = (memory[(x+1),y] = node.TopRightChild.Data).Color;
                shadow[x-sx,y-sy] = (memory[x,y] = node.TopLeftChild.Data).Color;
            }
            else {
                int size = 1 << level;
                ushort pid = node.Data.ID;
                ushort rid = node.Data.RiverID;
                byte border = node.Data.Border;

                int topleft = node.Data.Color << 16;
                int bottomright = (shadow[x-sx+size, y-sy+size]) << 16;
                int topright = (shadow[x-sx+size, y-sy]) << 16;
                int bottomleft = (shadow[x-sx, y-sy+size]) << 16;

                int leftstep = (bottomleft - topleft) >> node.Level;
                int rightstep = (bottomright - topright) >> node.Level;
                int left = topleft;
                int right = topright;

                // Do the interpolation
                int xstep = (right - left) >> level;
                int light = left;

                for ( int a = 0; a<size; a++ ) { // Loop horizontally
                    shadow[x-sx+a, y-sy] = (byte)(light>>16);
                    light += xstep;
                }

                for ( int b = 0; b < size; b++ ) { // Loop vertically
                    xstep = (left - right) >> level;
                    light = left;

                    shadow[x-sx, y-sy+b] = (byte)(left>>16);

                    if ( xstep == 0 ) {
                        for ( int a = 0; a<size; a++ ) { // Loop horizontally
                            memory[(x+a),(y+b)].Color = (byte)((light+0x8000)>>16);
                            memory[(x+a),(y+b)].ID = pid;
                            memory[(x+a),(y+b)].RiverID = rid;
                            memory[(x+a),(y+b)].Border = border;
                        }
                    }
                    else if ( size == 1 ) {
                        memory[(x),(y+b)].Color = (byte)((light+0x8000)>>16);
                        memory[(x),(y+b)].ID = pid;
                        memory[(x),(y+b)].RiverID = rid;
                        memory[(x),(y+b)].Border = border;
                    }
                    else {
                        int prevlight = light;
                        int preva = 0;
                        for ( int a = 0; a<size; a++ ) { // Loop horizontally
                            if ( light != prevlight ) { // Do as little as decoding as possible...
                                for ( int a2=preva; a2<a; ++a2 ) {
                                    memory[(x+a2),(y+b)].Color = (byte)((prevlight+0x8000)>>16);
                                    memory[(x+a2),(y+b)].ID = pid;
                                    memory[(x+a2),(y+b)].RiverID = rid;
                                    memory[(x+a2),(y+b)].Border = border;
                                }
                                preva = a;
                                prevlight = light;
                            }

                            light -= xstep;
                        }
                        if ( preva<size ) {
                            for ( int a2=preva; a2<size; ++a2 ) {
                                memory[(x+a2),(y+b)].Color = (byte)((prevlight+0x8000)>>16);
                                memory[(x+a2),(y+b)].ID = pid;
                                memory[(x+a2),(y+b)].RiverID = rid;
                                memory[(x+a2),(y+b)].Border = border;
                            }
                        }
                    }

                    left += leftstep;
                    right += rightstep;
                }
            }
        }
Пример #19
0
 private void BottomRightWalker( Node node, int x, int y )
 {
     if ( node.IsLeaf() )
         shadow[Lightmap.BlockSize,Lightmap.BlockSize] = node.Data.Color;
     else
         shadow[Lightmap.BlockSize,Lightmap.BlockSize] = node.TopLeftChild.Data.Color;
 }
Пример #20
0
        public static MapBlock Combine( MapBlock bottomright, MapBlock bottomleft, MapBlock topright, MapBlock topleft )
        {
            // Merge 4 trees
            Node root = new Node( false, bottomright.Tree.Level+1 );
            root.BottomRightChild = bottomright.Tree.Clone();
            root.BottomLeftChild = bottomleft.Tree.Clone();
            root.TopRightChild = topright.Tree.Clone();
            root.TopLeftChild = topleft.Tree.Clone();

            // Use for new block
            MapBlock result = new MapBlock( root );

            // Clip the tree
            result.WalkTree( new MapBlockHandling.TreeClipper() );
            result.tree.Level = 5;

            // Optimise the tee
            result.WalkTree( new MapBlockHandling.TreeOptimiser( true ) );

            return result;
        }
Пример #21
0
        private void DrawNode( Node node, Graphics g, int x, int y )
        {
            int color = shades[((rangecheck[(node.Data.Color-0+128+32)]<<6) | (int)(provinces[node.Data.ID].Terrain.Color) )];

            unchecked {
                using ( Brush b = new SolidBrush( Color.FromArgb( (int)(0xFF000000) | color ) ) ) {
                    g.FillRectangle( b, x, y, VisSize << node.Level, VisSize << node.Level );
                }
            }
            Brush fb = node.Data.IsBorder() ? Brushes.Red : Brushes.Black;

            g.FillRectangle( Brushes.White, x+2, y+2, VisSize-4, 8 );
            g.FillRectangle( Brushes.White, x+2, y+11, VisSize-4, 8 );
            g.FillRectangle( Brushes.White, x+2, y+20, VisSize-4, 8 );

            using ( StringFormat sf = new StringFormat( StringFormatFlags.NoWrap ) ) {
                sf.Alignment = StringAlignment.Center;
                using ( Font f = new Font( "Tahoma", 5.0F ) ) {
                    g.DrawString( node.Data.ID.ToString(), f, fb, new RectangleF( x+2, y+2, VisSize-4, 8 ), sf );
                    g.DrawString( node.Data.RiverID.ToString(), f, fb, new RectangleF( x+2, y+11, VisSize-4, 8 ), sf );
                    g.DrawString( node.Data.Color.ToString(), f, fb, new RectangleF( x+2, y+20, VisSize-4, 8 ), sf );
                }
            }
        }
Пример #22
0
 private void PaintWalker( Node node, int x, int y )
 {
     Pen pen;
     //paintgraphics.DrawRectangle( pen, x*20 + (5-node.Level), y*20 + (5-node.Level), 20*(1<<node.Level)-(5-node.Level)*2, 20*(1<<node.Level)-(5-node.Level)*2 );
     if ( node.IsLeaf() ) {
         PaintNode( node, x, y );
         pen = Pens.Red;
     }
     else {
         pen = Pens.Blue;
         PaintNode( node.BottomRightChild, x+1, y+1 );
         PaintNode( node.BottomLeftChild, x, y+1 );
         PaintNode( node.TopRightChild, x+1, y );
         PaintNode( node.TopLeftChild, x, y );
     }
     paintgraphics.DrawRectangle( pen, x*20 + 1, y*20 + 1, 20*(1<<node.Level)-2, 20*(1<<node.Level)-2 );
 }
Пример #23
0
 protected override void OnVisitNode( Node node, int x, int y )
 {
     visitor( node, x, y );
 }