fCraft.DrawCommands.DrawEllipsoid C# (CSharp) Method

DrawEllipsoid() static private method

static private DrawEllipsoid ( Player player, Position marks, object tag ) : void
player Player
marks Position
tag object
return void
        static void DrawEllipsoid( Player player, Position[] marks, object tag ) {
            player.drawingInProgress = true;
            Block drawBlock = (Block)tag;

            // find start/end coordinates
            int sx = Math.Min( marks[0].x, marks[1].x );
            int ex = Math.Max( marks[0].x, marks[1].x );
            int sy = Math.Min( marks[0].y, marks[1].y );
            int ey = Math.Max( marks[0].y, marks[1].y );
            int sh = Math.Min( marks[0].h, marks[1].h );
            int eh = Math.Max( marks[0].h, marks[1].h );

            int blocks;
            byte block;
            int step = 8;

            blocks = (ex - sx + 1) * (ey - sy + 1) * (eh - sh + 1);
            if( blocks > 2000000 ) {
                player.Message( "NOTE: This draw command is too massive to undo." );
            }

            // find axis lengths
            double rx = (ex - sx + 1) / 2 + .25;
            double ry = (ey - sy + 1) / 2 + .25;
            double rh = (eh - sh + 1) / 2 + .25;

            double rx2 = 1 / (rx * rx);
            double ry2 = 1 / (ry * ry);
            double rh2 = 1 / (rh * rh);

            // find center points
            double cx = (ex + sx) / 2;
            double cy = (ey + sy) / 2;
            double ch = (eh + sh) / 2;

            // prepare to draw
            player.drawUndoBuffer.Clear();

            blocks = (int)(Math.PI * 0.75 * rx * ry * rh);
            if( blocks > 2000000 ) {
                player.Message( "NOTE: This draw command is too massive to undo." );
            }

            for( int x = sx; x <= ex; x += step ) {
                for( int y = sy; y <= ey; y += step ) {
                    for( int h = sh; h <= eh; h += step ) {

                        for( int h3 = 0; h3 < step && h + h3 <= eh; h3++ ) {
                            for( int y3 = 0; y3 < step && y + y3 <= ey; y3++ ) {
                                for( int x3 = 0; x3 < step && x + x3 <= ex; x3++ ) {

                                    // get relative coordinates
                                    double dx = (x + x3 - cx);
                                    double dy = (y + y3 - cy);
                                    double dh = (h + h3 - ch);

                                    // test if it's inside ellipse
                                    if( (dx * dx) * rx2 + (dy * dy) * ry2 + (dh * dh) * rh2 <= 1 ) {
                                        block = player.world.map.GetBlock( x + x3, y + y3, h + h3 );
                                        if( block == (byte)drawBlock ) continue;
                                        if( block == (byte)Block.Admincrete && !player.Can( Permissions.DeleteAdmincrete ) ) continue;
                                        player.drawUndoBuffer.Enqueue( new BlockUpdate( Player.Console, x + x3, y + y3, h + h3, block ) );
                                        player.world.map.QueueUpdate( new BlockUpdate( Player.Console, x + x3, y + y3, h + h3, (byte)drawBlock ) );
                                    }
                                }
                            }
                        }
                    }
                }
            }
            player.drawingInProgress = false;
            player.Message( "Drawing " + blocks + " blocks... The map is now being updated." );
            player.world.log.Log( "{0} initiated drawing a cuboid containing {1} blocks of type {2}.", LogType.UserActivity,
                                  player.name,
                                  blocks,
                                  drawBlock.ToString() );
            GC.Collect();
        }
    }