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 ); }
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; } } }
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; } } }
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 ); } } }