Exemple #1
0
        /// <summary>
        /// Redraw the specified region.
        /// Should be used only from the draw() method.
        /// </summary>
        /// <param name="rectAB">Rectangle in the (A,B) coordinates.</param>
        /// <param name="overlay"></param>
        public void Draw(Rectangle rectAB, IMapOverlay overlay)
        {
            // the same rectangle in the client coordinates
            Rectangle rectClient = fromABToClient(rectAB);

            int  waterLevel  = world.WaterLevel;
            bool noHeightCut = (HeightCutHeight == world.Size.z - 1);

            Color waterSurfaceColor = waterSurfaceDayColor;

            if (world.ViewOptions.UseNightView)
            {
                waterSurfaceColor = ColorMap.getNightColor(waterSurfaceColor);
            }

            rectAB.Inflate(20, 20);
            if (rectAB.X < 0)
            {
                rectAB.X = 0;
            }
            if (rectAB.Y < 0)
            {
                rectAB.Y = 0;
            }
            if ((rectAB.Width + rectAB.X) > offscreenBuffer.Size.Width)
            {
                rectAB.Width = (rectAB.Width - rectAB.X);
            }
            if ((rectAB.Height + rectAB.Y) > offscreenBuffer.Size.Height)
            {
                rectAB.Height = (rectAB.Height - rectAB.Y);
            }

            //if (rectClient. > offscreenBuffer.clipRect)
            //dirtyRect.add(rectClient);
            offscreenBuffer.ClipRect = rectAB;     // set clipping

            Rectangle rectHV = fromABToHV(rectAB); // determine the region to draw

            int Hmax = Math.Min(rectHV.Right, world.Size.x - 1);

            int Zinit = noHeightCut ? (int)waterLevel : 0;      // no need to draw underwater unless in the height cut mode
            int Z     = HeightCutHeight;
            int Vmax  = Math.Min(rectHV.Bottom + Z * 2, world.Size.y - 1);

            emptyChip = ResourceUtil.GetGroundChip(world);
            waterChip = ResourceUtil.UnderWaterChip;

            for (int v = Math.Max(0, rectHV.Top); v <= Vmax; v++)
            {
                for (int h = rectHV.Left; h <= Hmax; h++)
                {
                    int groundLevel = world.getGroundLevelFromHV(h, v);


                    int zi = Zinit;
                    if (Zinit <= groundLevel && !shouldDrawGround(h, v, Zinit))
                    {
                        zi = Math.Max(zi - 1, 0);                                                               // if the surface is being cut, start from one smaller
                    }
                    for (int z = zi; z <= Z; z++)
                    {
                        Voxel voxel = world.voxelHVD(h, v, z);
                        //						if(voxel!=null)
                        //							Debug.Assert( voxel.location==world.toXYZ(h,v,z) );

                        // point in the client coordinate to draw
                        Point pt = fromHVZToClient(h, v, z);
                        // draw the surface anyway.

                        if (voxel == null || voxel.Transparent)
                        {
                            if (z == groundLevel)
                            {
                                if (shouldDrawGround(h, v, z))
                                {
                                    if (waterLevel <= z)
                                    {
                                        //DateTime start = DateTime.Now;
                                        emptyChip.Draw(drawContext.Surface, pt);
                                        //Debug.WriteLine(z + "[3]: " + (DateTime.Now - start).TotalMilliseconds + "ms, ");
                                    }
                                    else
                                    {
                                        waterChip.Draw(drawContext.Surface, pt);
                                    }
                                }
                            }
                            else
                            if (z == waterLevel && noHeightCut)
                            {
                                emptyChip.DrawShape(drawContext.Surface, pt, waterSurfaceColor);
                            }
                            else
                            if (z == Z && Z < groundLevel)
                            {
                                // if the surface voxel is not drawn, draw the "under group" chip
                                if (shouldDrawGround(h, v, z))
                                {
                                    ResourceUtil.UnderGroundChip.Draw(drawContext.Surface, pt);
                                }
                            }
                        }
                        //					}
                        //				}
                        //			}
                        //
                        //			for( int v=Math.Max(0,rectHV.Top); v<=Vmax; v++ )
                        //			{
                        //				for( int h=rectHV.Left; h<=Hmax; h++ )
                        //				{
                        //					int groundLevel = world.getGroundLevelFromHV(h,v);
                        //
                        //					int zi = Zinit;
                        //					if( Zinit<=groundLevel && !shouldDrawGround(h,v,Zinit) )
                        //						zi = Math.Max(zi-1,0);	// if the surface is being cut, start from one smaller
                        //					for( int z=zi; z<=Z; z++  )
                        //					{
                        //						Voxel voxel = world.voxelHVD(h,v,z);
                        //						//						if(voxel!=null)	Debug.Assert( voxel.location==world.toXYZ(h,v,z) );
                        //
                        //						if( z<groundLevel && z<heightCutHeight ) continue;
                        //						Point pt = fromHVZToClient(h,v,z);

                        if (voxel != null)
                        {
                            //DateTime start = DateTime.Now;
                            voxel.DrawVoxel(drawContext, pt, noHeightCut ? -1 : (Z - z + 1));
                            //Debug.WriteLine("voxel took: " + (DateTime.Now - start).TotalMilliseconds + "ms");
                        }
                        if (overlay != null)
                        {
                            overlay.DrawVoxel(this, drawContext, world.toXYZ(h, v, z), pt);
                        }
                    }
                    // Debug.WriteLine("outer loop took: " + (DateTime.Now - start).TotalMilliseconds + "ms");
                }
            }

            if (Core.Options.drawBoundingBox)
            {
                rectAB.Inflate(-1, -1);
                offscreenBuffer.DrawBox(rectAB);
            }
        }