#!/usr/bin/perl # ------------- FileCityMap ----------------- # written by Elliot Mousseau # based on some examples I found here --> http://www.perl.com/pub/a/2004/12/01/3d_engine.html # # I am new to OpenGL so this script is still a little buggy # # if you have any desire to modify this please do # you should also tell me about it because I enjoy learning things # my e-mail is ourlivesarepointless@yahoo.com # # know bugs/updates are found here -> http://3dcitymap.homeunix.com:441/ # BEGIN{ unshift(@INC,"../blib"); } # in case OpenGL is built but not installed BEGIN{ unshift(@INC,"../blib/arch"); } # 5.002 gamma needs this BEGIN{ unshift(@INC,"../blib/lib"); } # 5.002 gamma needs this BEGIN { $| = 1; unshift @INC, './lib'; unshift @INC, '../lib'; unshift @INC, '../blib/arch/'; } my $specarg = $ARGV[0]; use OpenGL; use strict; use warnings; use constant PI => 4 * atan2(1, 1); use Cwd; use IO::File; use File::Basename; use SDL::App; use SDL::Constants; use SDL::Event; use SDL::OpenGL; use Math::Complex; my $feelgravity="on"; my %objects; my @objects; my(%locatex, %locatey, %locatez); my $copycolors; my $height=2; my $speed_move=11; my $viewdist=4000; my $housecount=0; my $here = cwd; my $known; my $plus=0; my $maxwhy; my $maxexe; my $rot=0; my $pollution="off"; my $speed_yaw = 36; my $spot=0; my $piccount=0; my $showfigure="no"; my %bomb; my @bomb; my %nuke; my @nuke; my %nukecenter; my @nukecenter; my %flames; my @flames; my %floor; my @floor; my $light=0; my %figure; my @figure; my $floortriger="on"; my %missle; my @missle; my %missle2; my @missle2; my %snow; my @snow; my $mygravity=1; my $falling = "on"; my $wayfalling = "off"; my %rain; my @rain; my $groundcount=0; my $xwind=.5; my $zwind=.5; my $gravspeed=2; my $gravity=1; my $control; my($newwhy, $oldwhy); my $misslenum=0; use Net::SSH::Perl; use Net::SSH::Perl::Cipher; my($ssh, $user, $pass, $this_user); my ($host, $port, $ciph, $c, $ssh, $this_user, $pass); chomp(my $this_host = `hostname`); if($specarg =~ /-c/) { print "Enter a host name to connect to: [$this_host] "; chomp($host = ); print "\n"; print "Enter the port number of the remote sshd: [ssh] "; chomp($port = ); print "\n"; print "Choose a cipher from the list:\n"; my $supp = Net::SSH::Perl::Cipher::supported(); for $ciph (sort @$supp) { printf " [%d] %s\n", $ciph, Net::SSH::Perl::Cipher::name($ciph); } printf "Enter a number: [%d] ", Net::SSH::Perl::Cipher::id('IDEA'); chomp($c = ); print "\n"; $ssh = Net::SSH::Perl->new($host || $this_host, port => $port || 'ssh', cipher => Net::SSH::Perl::Cipher::name($c), debug => 1); $this_user = scalar getpwuid($<); print "Enter your username on that host: [$this_user] "; chomp($user = ); use Term::ReadKey; print "And your password: "; ReadMode('noecho'); chomp($pass = ReadLine(0)); ReadMode('restore'); print "\n"; } START: __PACKAGE__->new->main; sub new { my $class = shift; my $self = bless {}, $class; return $self; } sub main { my $self = shift; $self->init; $self->main_loop; $self->cleanup; } sub init { my $self = shift; $| = 1; $self->init_conf; $self->init_window; $self->init_event_processing; $self->init_command_actions; $self->init_view; $self->init_time; $self->init_objects; } sub init_conf { my $self = shift; $self->{conf} = { title => 'FileCityMap', width => 900, height => 700, fovy => 90, bind => { escape => 'quit', f1 => 'screenshot', 1 => 'speeddown', 2 => 'speedup', 3 => 'yawdown', 4 => 'yawup', 5 => 'distdown', 6 => 'distup', a => '+move_left', d => '+move_right', w => '+move_forward', s => '+move_back', up => '+move_up', down => '+move_down', left => '+yaw_left', right => '+yaw_right', tab => '+look_behind', e => '+move_down', r => '+move_up', m => 'move_waydown', j => 'move_wayup', u => 'move_waywayup', f => 'fire', n => 'nuke', space => 'missle', t => 'missle2', g => 'gravity_switch', p => 'pollute_world', y => 'showdir', b => 'gobackdir', h => 'gohomedir', i => 'reset_view', k => 'toggle_figure', 9 => 'add_snow', 0 => 'add_rain', 8 => 'kill_rain', 7 => 'kill_snow', l => 'draw_floor', c => 'change_control', } }; } sub init_window { my $self = shift; my $title = $self->{conf}{title}; my $w = $self->{conf}{width}; my $h = $self->{conf}{height}; $self->{resource}{sdl_app} = SDL::App->new(-title => $title, -width => $w, -height => $h, -gl => 1, ); SDL::ShowCursor(0); } sub init_event_processing { my $self = shift; $self->{resource}{sdl_event} = SDL::Event->new; $self->{lookup}{event_processor} = { &SDL_QUIT => \&process_quit, &SDL_KEYUP => \&process_key, &SDL_KEYDOWN => \&process_key, }; } sub init_command_actions { my $self = shift; $self->{lookup}{command_action} = { quit => \&action_quit, screenshot => \&action_screenshot, speedup => \&action_speedup, speeddown => \&action_speeddown, yawup => \&action_yawup, yawdown => \&action_yawdown, distup => \&action_distup, distdown => \&action_distdown, fire => \&action_fire, nuke => \&action_nuke, missle => \&action_missle, missle2 => \&action_missle2, gravity_switch => \&gravity_switch, pollute_world => \&action_pollute, showdir => \&action_showdir, gobackdir => \&action_backdir, gohomedir => \&action_homedir, reset_view => \&action_reset_view, toggle_figure => \&action_toggle_figure, add_snow => \&add_snow, add_rain => \&add_rain, kill_snow => \&kill_snow, draw_floor => \&draw_floor, change_control => \&change_control, kill_rain => \&kill_rain, move_waydown => \&action_waydown, move_wayup => \&action_wayup, move_waywayup => \&action_waywayup, '+move_up' => \&action_moveup, '+move_down' => \&action_movedown, # '+move_up' => \&action_move, # '+move_down' => \&action_move, '+move_left' => \&action_move, '+move_right' => \&action_move, '+move_forward' => \&action_move, '+move_back' => \&action_move, # '+yaw_up' => \&action_moveup, # '+yaw_down' => \&action_moveup, '+yaw_left' => \&action_move, '+yaw_right' => \&action_move, '+look_behind' => \&action_move, }; } sub init_view { my $self = shift; $self->{world}{view} = { position => [-5, $height, -5], orientation => [180, 0 , 1, 0], d_yaw => 0, yaw => 0, v_forward => 0, v_right => 0, dv_yaw => 0, dv_forward => 0, dv_right => 0, }; } sub init_time { my $self = shift; $self->{world}{time} = now(); } sub init_objects { $plus=0; $spot=0; $maxwhy=0; $maxexe=0; $housecount=0; $here = cwd; $#objects = -1; my $self = shift; my($ls); if($specarg =~ /-c/) { my $list = "ls -ap --width=5"; $ssh->login($user || $this_user, $pass); chomp(my $cmd = $list); my($out, $err) = $ssh->cmd($cmd || "ls -ap --width=5"); print "$out\n"; $ls = $out; } else { $ls = `ls -ap --width=5`; } open(TEMP, ">/tmp/listing"); print TEMP $ls; close(TEMP); $ls =~ s/\,//g; $ls =~ s/\n/ \, /g; my @FileArray = grep { ! /^\s*$/ } split /\,/, $ls; # my @FileArray = split /\,/, $ls; # print "\n\n\n\n@FileArray\n\n\n\n"; my %listhash=@FileArray; my $fileident; my $exe=0; my $why=0; my $rowx=0; my $rowy=0; my $size=2; my $filecount; open(TEMP, "/tmp/listing"); while($fileident = ) { # foreach $fileident (keys %listhash) { $filecount++; # print "$fileident\n"; } my $squared = sqrt($filecount); # $squared = int($squared); $rowx=0; print "\ncreating scene (\"$here\")\n"; open(TEMP, "/tmp/listing"); while($fileident = ) { $fileident =~ s/\n//g; $known=""; # foreach $fileident (keys %listhash) { $fileident =~ s/\[//g; $fileident =~ s/\]//g; $fileident =~ s/\+//g; $exe=($exe+10); if($exe>$maxexe) { $maxexe=$exe; } $rowx++; # if($rowx>($squared)) { $plus=$exe; if($rowy>($squared)) { $rowy=0; $rowx++; $newwhy=($why-$oldwhy); # $spot=($spot+$newwhy); $spot=($spot+150); $oldwhy=$exe; $why=0; } if($rowx>(4)) { $exe=$spot; $rowx=0; $rowy++; $why=($why+15); if($why>$maxwhy) { $maxwhy=$why; } } if($fileident =~ /\//) { unless($known eq "yes") { $locatex{$fileident}=$exe; $locatey{$fileident}=$why; if($fileident =~ /\.\./) { push @objects, { lit => 1, color => [ -1, .3, .1], position => [ $exe, 4, $why], orientation => [90, 0, 90, 0], scale => [3, 4, 3], draw => \&draw_shape, }; } elsif($fileident =~ /\./) { my $random_alt = int(rand 40); unless($fileident eq "./") { $locatez{$fileident}=(125+$random_alt); push @objects, { lit => 1, color => [ .2, 1, 1], position => [ $exe, (125+$random_alt), $why], orientation => [90, 0, 90, 0], scale => [2, 2, 2], draw => \&draw_sphere, }; } } else { push @objects, { lit => 1, color => [ .2, 1, 1], position => [ $exe, 4, $why], orientation => [0, 0, 0, 0], scale => [2, 4, .2], draw => \&draw_cube, }; } $known = "yes"; print "[$locatey{$fileident} , $locatex{$fileident}] => $fileident\n"; } } if($fileident =~ /\.tar|\.tgz/) { unless($known eq "yes") { $copycolors = "1,1,1"; push @objects, { lit => 50, color => [ .1, .1, .1], position => [ $exe, .8, $why], orientation => [0, 0, 0, 0], scale => [.5, 1, .5], draw => \&draw_trash_can, }; $known = "yes"; } } if($fileident =~ /\.jpg|\.JPG|\.bmp|\.BMP\.png|\.PNG|\.gif|\.GIF/) { unless($known eq "yes") { $copycolors = "0,1,1"; push @objects, { lit => 1, color => [ 1, 1, 1], position => [ $exe, 2, $why], orientation => [0, 0, 0, 0], scale => [2, 2, 2], draw => \&draw_cube, }; $known = "yes"; } } if($fileident =~ /\.mp3|\.MP3|\.wma|\.WMA|\.wav|\.WAV/) { unless($known eq "yes") { $copycolors = "1,0,1"; $fileident =~ s/\)//g; $fileident =~ s/\(//g; push @objects, { lit => 1, color => [ 1, 0, 1], position => [ $exe, 2, $why], # orientation => [45, 0, 45, 45], orientation => [0, 0, 0, 0], scale => [1, 2, 1], draw => \&draw_mp3, }; $known = "yes"; } } if($fileident =~ /\.pl/) { unless($known eq "yes") { $copycolors = "1,1,0"; my $random = int(rand 2); # my $random=0; $why=($why+(7.5/2)); $exe=($exe+(7.5/2)); if($exe>$maxexe) { $maxexe=$exe; } if($why>$maxwhy) { $maxwhy=$why; } if($random==0) { push @objects, { position => [ $exe, 3, ($why)], orientation => [90, 0, 90, 0], scale => [1, 1, 1], draw => \&draw_stop_sign, }; } else { push @objects, { position => [ $exe, 3, ($why)], orientation => [0, 0, 0, 0], scale => [1, 1, 1], draw => \&draw_stop_sign, }; } $why=($why+(7.5/2)); if($why>$maxwhy) { $maxwhy=$why; } $known = "yes"; } } if($fileident =~ /\.exe/) { unless($known eq "yes") { $copycolors = "1,0,0"; push @objects, { lit => 1, color => [ .1, 0, .1], position => [ $exe, $size, $why], orientation => [0, 0, 0, 0], scale => [3, $size, 3], draw => \&draw_cube, }; $known = "yes"; } } $here = cwd; if($here =~ /\/dev/) { unless($known eq "yes") { $copycolors = "1,1,1"; push @objects, { lit => 50, color => [ .1, .1, .1], position => [ $exe, 1, $why], orientation => [0, 0, 0, 0], scale => [1, 1, 1], draw => \&draw_device, }; $known = "yes"; } } unless($known eq "yes") { unless($fileident =~ /\//) { $size = `ls -s $fileident`; $size =~ s/\n//g; $size =~ s/ $fileident//g; $size =~ tr/[0-9]//c; } else { $size=4; } unless($size<=0) { if($size<=2) { while($size<2) { $size=($size*2); # print "$fileident => $size\n"; } } # if($size>=100000) { # print "$size $fileident\n"; # while($size>35) { # $size=($size-3); # } # } if($size>15) { while($size>15) { $size=($size-6); } } } else { $size=2; } if($size<=8) { my $girth=($size/2); $exe=($exe+($girth*2)+3); if($exe>$maxexe) { $maxexe=$exe; } push @objects, { lit => 1, position => [ $exe, $size, $why], orientation => [0, 0, 0, 0], scale => [$girth, $size, $girth], draw => \&draw_tree, }; } if(($size>8)&&($size<=15)) { my $girth=($size/2); my $zgirth=($girth/2); if($girth>=15) { $girth=14; } if($zgirth>=7) { $zgirth=7; } $exe=($exe+(($girth*2)+10)); if($exe>$maxexe) { $maxexe=$exe; } $housecount++; if($housecount>45) { $housecount=1; } if( ($housecount<=15)&&($housecount>0)) { push @objects, { lit => 1, position => [ $exe, $size, $why], orientation => [0, 0, 0, 0], scale => [$girth, $size, $zgirth], draw => \&draw_house, }; } if( ($housecount<=30)&&($housecount>15)) { push @objects, { lit => 1, position => [ $exe, $size, $why], orientation => [0, 0, 0, 0], scale => [$girth, $size, $zgirth], draw => \&draw_house2, }; } if( ($housecount<=45)&&($housecount>30)) { push @objects, { lit => 1, position => [ $exe, ($size/2), $why], orientation => [0, 0, 0, 0], scale => [$girth, ($size/2), $zgirth], draw => \&draw_house3, }; } } if($size>15) { $exe=($exe+13); if($exe>$maxexe) { $maxexe=$exe; } push @objects, { lit => 1, position => [ $exe, $size, $why], orientation => [0, 0, 0, 0], scale => [5, $size, 5], draw => \&draw_sky_scraper, }; } } # print "X:$exe Y:$why File:$fileident Size:$size\n"; } $self->{world}{objects} = \@objects; } sub main_loop { my $self = shift; my $view = $self->{world}{view}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; while (not $self->{state}{done}) { $self->{state}{frame}++; $self->update_time; $self->do_events; } } sub update_time { my $self = shift; my $now = now(); $self->{world}{d_time} = $now - $self->{world}{time}; $self->{world}{time} = $now; } sub now { return SDL::GetTicks() / 500; } sub do_events { my $self = shift; $self->update_view; $self->do_frame; my $queue = $self->process_events; my $lookup = $self->{lookup}{command_action}; my ($command, $action); while (not $self->{state}{done} and @$queue) { my @args; $command = shift @$queue; ($command, @args) = @$command if ref $command; $action = $lookup->{$command} or next; $self->$action($command, @args); } } sub process_events { my $self = shift; my $event = $self->{resource}{sdl_event}; my $lookup = $self->{lookup}{event_processor}; my ($process, $command, @queue); $event->pump; while (not $self->{state}{done} and $event->poll) { $process = $lookup->{$event->type} or next; $command = $self->$process($event); push @queue, $command if $command; } return \@queue; } sub process_quit { my $self = shift; $self->{state}{done} = 1; return 'quit'; } sub process_key { my $self = shift; my $event = shift; my $symbol = $event->key_sym; my $name = SDL::GetKeyName($symbol); my $command = $self->{conf}{bind}{$name} || ''; my $down = $event->type == SDL_KEYDOWN; if ($command =~ /^\+/) { return [$command, $down]; } else { return $down ? $command : ''; } } sub action_quit { my $self = shift; $self->{state}{done} = 1; } sub action_reset_view { my $self = shift; $light=0; $self->set_world_lights; $self->init_view; $self->init_time; } sub action_toggle_figure { if($showfigure eq "yes") { $showfigure="no"; } else { $showfigure="yes"; } # my $self = shift; # $self->update_view; } sub action_pollute { my $self = shift; if($pollution =~ /on/) { $pollution="off"; } else { $pollution="on"; } my $random_alt2; my $random_exe; my $random_why; my $cloud_count=0; my $whygirth=15; my $whyswitch="plus"; # $self->init_view; # $self->init_time; $self->init_objects; if($pollution eq "on") { while($cloud_count<2400) { if($whyswitch eq "plus") { $whygirth++; if($whygirth>40) { $whyswitch="minus"; } } if($whyswitch eq "minus") { $whygirth=($whygirth-1); if($whygirth<10) { $whyswitch="plus"; } } $random_alt2 = (rand $whygirth); $random_exe = (rand 600); $random_why = (rand 600); $cloud_count++; push @objects, { lit => 1, color => [ .1, .1, .1], position => [ $random_exe, (45+$random_alt2), $random_why], orientation => [90, 0, 90, 0], scale => [1, 1, 1], draw => \&draw_sphere, }; } } } sub action_yawup { $speed_yaw++; $speed_yaw++; $speed_yaw++; $speed_yaw++; $speed_yaw++; print "($speed_yaw)\n"; } sub action_yawdown { unless($speed_yaw<=5) { $speed_yaw=($speed_yaw-5); print "($speed_yaw)\n"; } } sub action_showdir { $here = cwd; print "$here\n"; } sub action_backdir { my $self = shift; chdir "../"; $here = cwd; print "Went back to\n$here"; $self->init; } sub action_homedir { my $self = shift; my $user = `whoami`; $user =~ s/\n//g; chdir "/home/$user"; $here = cwd; print "Went back to\n$here"; $self->init; } sub action_fire { my $self = shift; my $view = $self->{world}{view}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; my $o1=$angle; my $missle_speed=1; my ($zspeed, $xspeed); if(($o1>270)||($o1<90)) { # lower quadrant if($o1>270) { # lower left quadrant $zspeed=(($o1-270)/90); $zspeed=($zspeed*$missle_speed); $z=($z-$zspeed); $xspeed=(($o1-360)/90); $xspeed=($xspeed*$missle_speed); $x=($x-$xspeed); } else { # lower right quadrant $zspeed=(($o1-90)/90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=($o1/90); $xspeed=($xspeed*$missle_speed); $x=($x-$xspeed); } } else { # upper quadrant if($o1>180) { # top left quadrant $zspeed=(($o1-270)/-90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=(($o1-180)/90); $xspeed=($xspeed*$missle_speed); $x=($x+$xspeed); } else { # top right quadrant $zspeed=(($o1-90)/90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=(($o1-180)/90); $xspeed=($xspeed*$missle_speed); $x=($x+$xspeed); } } print "planting bomb\n"; push @bomb, { lit => 1, color => [ 1, 0, 0], position => [ $x, $y, $z], orientation => [$angle, @axis], scale => [.5, 2.5, .5], draw => \&draw_cube, }; $self->{world}{bomb} = \@bomb; } sub action_nuke { my $self = shift; my $view = $self->{world}{view}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; my $o1=$angle; my $missle_speed=2; my ($zspeed, $xspeed); if(($o1>270)||($o1<90)) { # lower quadrant if($o1>270) { # lower left quadrant $zspeed=(($o1-270)/90); $zspeed=($zspeed*$missle_speed); $z=($z-$zspeed); $xspeed=(($o1-360)/90); $xspeed=($xspeed*$missle_speed); $x=($x-$xspeed); } else { # lower right quadrant $zspeed=(($o1-90)/90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=($o1/90); $xspeed=($xspeed*$missle_speed); $x=($x-$xspeed); } } else { # upper quadrant if($o1>180) { # top left quadrant $zspeed=(($o1-270)/-90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=(($o1-180)/90); $xspeed=($xspeed*$missle_speed); $x=($x+$xspeed); } else { # top right quadrant $zspeed=(($o1-90)/90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=(($o1-180)/90); $xspeed=($xspeed*$missle_speed); $x=($x+$xspeed); } } print "dropping bomb\n"; push @nuke, { lit => 1, color => [ 1, 0, 0], position => [ $x, ($y+2), $z], orientation => [$angle, @axis], scale => [.5, 2.5, .5], draw => \&draw_sphere, }; $self->{world}{nuke} = \@nuke; } sub action_missle { my $self = shift; my $view = $self->{world}{view}; my $missle = $self->{world}{missle}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; my $missle_count=0; foreach my $o (@$missle) { $missle_count++; } if($missle_count<=5) { print "firing missle\n"; push @missle, { lit => 1, color => [ 0, 0, 0], position => [ $x, $y-2, $z], orientation => [$angle, @axis], scale => [.25, .25, 4], draw => \&draw_missle, }; $self->{world}{missle} = \@missle; } else { print "too many missle on map\n"; } } sub action_missle2 { my $self = shift; my $view = $self->{world}{view}; my $missle2 = $self->{world}{missle2}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; my $missle_count2=0; foreach my $o (@$missle2) { $missle_count2++; } if($missle_count2<2) { if($y>20) { print "firing spiral missles\n"; my $spicount=0; while($spicount<15){ $spicount++; push @missle2, { lit => 1, color => [.9, .5, 0], position => [ $x, $y+$spicount, $z], orientation => [$angle, @axis], scale => [.125, 1, .25], draw => \&draw_sphere, }; } $self->{world}{missle2} = \@missle2; } else { print "you are too low to the ground\n"; } } else { print "you can only drop 1 spiral missle at a time\n"; } } sub action_moveup { if($feelgravity eq "on") { if($falling eq "off") { $falling="on"; print "falling\n"; } else { print "thrusting\n"; $falling="off"; } } else { if($mygravity>=0) { $mygravity=-$gravspeed; } else { $mygravity=0; } } } sub action_movedown { if($feelgravity eq "on") { if($wayfalling eq "off") { $wayfalling="on"; print "falling with thrusters\n"; } else { $wayfalling="off"; } } else { if($mygravity>0) { $mygravity=0; } else { $mygravity=$gravspeed; } } } sub add_snow { my $self= shift; my $peices=0; while($peices<500) { $peices++; my $snowx = (rand $maxexe); my $snowy = (rand 200); my $snowz = (rand $maxwhy); push @snow, { lit => 1, color => [ 1, 1, 1], position => [ ($snowx-100), $snowy, ($snowz-100)], orientation => [0, 0, 0, 0], scale => [.1, .1, .1], draw => \&draw_sphere, }; } print "adding snow\n"; $self->{world}{snow} = \@snow; } sub kill_snow { print "removing snow\n"; $#snow = -1; } sub kill_rain { my $self = shift; $#rain = -1; print "removing rain\n"; } sub add_rain { my $self= shift; my $peices=0; while($peices<500) { $peices++; my $rainx = (rand $maxexe); my $rainy = (rand 200); my $rainz = (rand $maxwhy); push @rain, { lit => 1, color => [ 0, 0, 1], position => [ ($rainx-100), $rainy, ($rainz-100)], orientation => [0, 0, 0, 0], scale => [.1, .25, .1], draw => \&draw_sphere, }; } print "adding rain\n"; $self->{world}{rain} = \@rain; } sub draw_floor { my $self= shift; my $peices=0; my $maxup; if($floortriger eq "on") { $floortriger = "off"; $#floor =-1; } else { $floortriger = "on"; $maxup=(($maxwhy+$maxexe)/2); push @floor, { lit => 1, color => [ 0.5, 0.9, 0.5], position => [ ($maxexe/2), -.25, ($maxwhy/2)], orientation => [0, 0, 0, 45], scale => [$maxexe, .125, $maxwhy], draw => \&draw_floor_sphere, }; } print "making floor\n"; $self->{world}{floor} = \@floor; } sub action_speedup { unless($speed_move>=160) { $speed_move=($speed_move+5); print "$speed_move\n"; } } sub action_speeddown { unless($speed_move<=1) { $speed_move=($speed_move-5); print "$speed_move\n"; } } sub action_up { my $self = shift; my $view = $self->{world}{view}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; print "move up ($y)\n"; $y++; my $angle2=($y*5); $self->{world}{view} = { position => [$x, $y, $z], orientation => [$angle, 0, 1,0], d_yaw => 0, v_yaw => 0, v_forward => 0, v_right => 0, dv_yaw => 0, dv_forward => 0, dv_right => 0, }; } sub action_down { my $self = shift; my $view = $self->{world}{view}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; my $angle2; unless($y<=1) { $y=($y-1); print "move down ($y)\n"; } $self->{world}{view} = { position => [$x, $y, $z], orientation => [$angle, 0, 1, 0], d_yaw => 0, v_yaw => 0, v_forward => 0, v_right => 0, dv_yaw => 0, dv_forward => 0, dv_right => 0, }; } sub action_waydown { my $self = shift; my $view = $self->{world}{view}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; my $angle2; $y=3; print "moved to floor level($y)\n"; $self->{world}{view} = { position => [$x, $y, $z], orientation => [$angle, 0, 1, 0], d_yaw => 0, v_yaw => 0, v_forward => 0, v_right => 0, dv_yaw => 0, dv_forward => 0, dv_right => 0, }; } sub action_wayup { my $self = shift; my $view = $self->{world}{view}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; my $angle2; $y=115; print "moved to cloud level ($y)\n"; $self->{world}{view} = { position => [$x, $y, $z], orientation => [$angle, 0, 1, 0], d_yaw => 0, v_yaw => 0, v_forward => 0, v_right => 0, dv_yaw => 0, dv_forward => 0, dv_right => 0, }; } sub action_waywayup { my $self = shift; my $view = $self->{world}{view}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; my $angle2; $y=250; print "moved to star level ($y)\n"; $self->{world}{view} = { position => [$x, $y, $z], orientation => [$angle, 0, 1, 0], d_yaw => 0, v_yaw => 0, v_forward => 0, v_right => 0, dv_yaw => 0, dv_forward => 0, dv_right => 0, }; } sub action_distdown { my $self = shift; unless($viewdist<=50) { $viewdist=($viewdist-50); $self->init_objects; } } sub action_distup { my $self = shift; $viewdist=($viewdist+50); $self->init_objects; } sub action_screenshot { my $self = shift; $self->{state}{need_screenshot} = 1; } sub action_move { my $self = shift; my ($command, $down) = @_; my $sign = $down ? 1 : -1; my $view = $self->{world}{view}; my %move_update = ( '+yaw_left' => [dv_yaw => $speed_yaw ], '+yaw_right' => [dv_yaw => -$speed_yaw ], # '+yaw_up' => [dh_yaw => $speed_move ], # '+yaw_down' => [dh_yaw => -$speed_move ], '+move_right' => [dv_right => $speed_move], '+move_left' => [dv_right => -$speed_move], '+move_forward' => [dv_forward => $speed_move], '+move_back' => [dv_forward => -$speed_move], '+look_behind' => [d_yaw => 180 ], ); my $update = $move_update{$command} or return; $view->{$update->[0]} += $update->[1] * $sign; } sub change_control { my $self = shift; my ($command, $down) = @_; my $sign = $down ? 1 : -1; my $view = $self->{world}{view}; my ($one, $two, $three, $four) = @{$view->{orientation}}; $control++; if($control==1) { $two=0; $four=90; } elsif($control==2){ $one=($one-180); $two=90; $four=0; } elsif($control==3){ $one=($one-180); $two=90; $four=90; } elsif($control==4){ $two=0; $four=0; } else { $control=0; } (@{$view->{orientation}}) = ($one, $two, $three, $four); } sub update_view { my $self = shift; my $view = $self->{world}{view}; my $d_time = $self->{world}{d_time}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; if($feelgravity eq "on") { if($falling eq "on") { unless($mygravity>5) { $mygravity=($mygravity+.01); } } else { unless($mygravity<-9) { if($mygravity>0) { $mygravity=($mygravity-.06); # } # elsif ($mygravity) { # $mygravity=($mygravity-.01); } else { $mygravity=($mygravity-.03); } } } if($wayfalling eq "on") { unless($mygravity>10) { $mygravity=($mygravity+.06); } } } $y=($y-$mygravity); if($y<=0) { $mygravity=0; } unless($y<1) { (@{$view->{position}}) = ($x, $y, $z); } my $o1 = $angle; until($o1<=360) { $o1=($o1-360); } until($o1>0) { $o1=($o1+360); } # print "$o1\n"; $view->{orientation}[0] += $view->{d_yaw}; $view->{d_yaw} = 0; $view->{v_yaw} += $view->{dv_yaw}; $view->{dv_yaw} = 0; $view->{orientation}[0] += $view->{v_yaw} * $d_time; $view->{v_right} += $view->{dv_right}; $view->{dv_right} = 0; $view->{v_forward} += $view->{dv_forward}; $view->{dv_forward} = 0; my $vx = $view->{v_right}; my $vz = -$view->{v_forward}; my $angle = $view->{orientation}[-0]; ($vx, $vz) = rotate_xz($angle, $vx, $vz); $view->{position}[0] += $vx * $d_time; $view->{position}[2] += $vz * $d_time; my $view = $self->{world}{view}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; my ($o1, $o2, $o3, $o4) = @{$view->{orientation}}; if($showfigure eq "yes") { # determine figure position my ($zspeed, $xspeed); my $missle_speed=2; # $#figure = -1; if(($o1>270)||($o1<90)) { # lower quadrant if($o1>270) { # lower left quadrant $zspeed=(($o1-270)/90); $zspeed=($zspeed*$missle_speed); $z=($z-$zspeed); $xspeed=(($o1-360)/90); $xspeed=($xspeed*$missle_speed); $x=($x-$xspeed); } else { # lower right quadrant $zspeed=(($o1-90)/90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=($o1/90); $xspeed=($xspeed*$missle_speed); $x=($x-$xspeed); } } else { # upper quadrant if($o1>180) { # top left quadrant $zspeed=(($o1-270)/-90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=(($o1-180)/90); $xspeed=($xspeed*$missle_speed); $x=($x+$xspeed); } else { # top right quadrant $zspeed=(($o1-90)/90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=(($o1-180)/90); $xspeed=($xspeed*$missle_speed); $x=($x+$xspeed); } push @figure, { lit => 1, color => [ .1, .5, .5], position => [ $x, $y, $z], orientation => [0, 0, 0, 0], scale => [.25, .25, .25], draw => \&draw_sphere, }; $self->{world}{figure} = \@figure; } } } sub rotate_xz { my ($angle, $x, $z) = @_; my $radians = $angle * PI / 180; my $cos = cos($radians); my $sin = sin($radians); my $rot_x = $cos * $x + $sin * $z; my $rot_z = -$sin * $x + $cos * $z; return ($rot_x, $rot_z); } sub do_frame { my $self = shift; $self->prep_frame; $self->draw_frame; $self->end_frame; } sub prep_frame { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glEnable(GL_DEPTH_TEST); glEnable(GL_COLOR_MATERIAL); glEnable(GL_NORMALIZE); } sub draw_frame { my $self = shift; $self->set_projection_3d; $self->set_eye_lights; $self->set_view_3d; $self->set_world_lights; $self->draw_view; } sub set_projection_3d { my $self = shift; my $fovy = $self->{conf}{fovy}; my $w = $self->{conf}{width}; my $h = $self->{conf}{height}; my $aspect = $w / $h; glMatrixMode(GL_PROJECTION); glLoadIdentity; gluPerspective($fovy, $aspect, 1, $viewdist); glMatrixMode(GL_MODELVIEW); glLoadIdentity; } sub set_eye_lights { glLight(GL_LIGHT1, GL_POSITION, 0.0, 0.0, 20.0, 1.0); glLight(GL_LIGHT1, GL_DIFFUSE, 45.0, 45.0, 45.0, 45.0); glLight(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.5); glLight(GL_LIGHT1, GL_SPOT_CUTOFF, 180.0); glLight(GL_LIGHT1, GL_SPOT_EXPONENT, 180.0); glEnable(GL_LIGHT1); } sub set_view_3d { my $self = shift; my $view = $self->{world}{view}; my ($angle, @axis) = @{$view->{orientation}}; my ($x, $y, $z) = @{$view->{position}}; # my ($mx,$my) = glpXQueryPointer; open(TEMP, "/tmp/listing"); while(my $fileident = ) { $fileident =~ s/\n//g; if($fileident =~ /\//) { # print "$locatex{$fileident} - $x $locatey{$fileident} - $z\n"; if($locatex{$fileident}<=0) { $locatex{$fileident}=0; } if($locatey{$fileident}<=0) { $locatey{$fileident}=0; } if( ( ($x < ($locatex{$fileident}+1.5) ) && ($x > ($locatex{$fileident}-1.5) ) && ($z < ($locatey{$fileident}+0.5) ) && ($z>($locatey{$fileident}-0.5) )&&( ($y>($locatez{$fileident}-4))&&($y<($locatez{$fileident}+4)) ) ) ) { chdir $fileident; print "$fileident\n"; $self->init_objects; } } } # print "$x, $y, $z \n"; glRotate(-$angle, @axis); glTranslate(-$x, -$y, -$z); } sub set_world_lights { glLight(GL_LIGHT0, GL_POSITION, 0.0, 0.0, 1.0, 0.0); glEnable(GL_LIGHT0); } sub draw_view { my $self = shift; $self->set_world_lights; my $objects = $self->{world}{objects}; foreach my $o (@$objects) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); glColor(@{$o->{color}}) if $o->{color}; glPushMatrix; glTranslate(@{$o->{position}}) if $o->{position}; glRotate(@{$o->{orientation}}) if $o->{orientation}; glScale(@{$o->{scale}}) if $o->{scale}; $o->{draw}->(); glPopMatrix; glFlush(); } my $nukecenter = $self->{world}{nukecenter}; foreach my $o (@$nukecenter) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); my ($sx, $sy, $sz) = (@{$o->{scale}}); $sx++; $sy++; $sy++; $sy++; $sy++; $sz++; (@{$o->{scale}}) = ($sx, $sy, $sz); glColor(@{$o->{color}}) if $o->{color}; glPushMatrix; glTranslate(@{$o->{position}}) if $o->{position}; glRotate(@{$o->{orientation}}) if $o->{orientation}; glScale(@{$o->{scale}}) if $o->{scale}; $o->{draw}->(); glPopMatrix; glFlush(); } my $flames = $self->{world}{flames}; my $flamecount=0; foreach my $o (@$flames) { $flamecount++; if($flamecount>1500) { $#flames = -1; $self->{world}{flames} = \@flames; } $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); my ($x, $y, $z) = (@{$o->{position}}); my ($sx, $sy, $sz) = (@{$o->{scale}}); $y=($y-1); unless($sx<=0) { $sx=($sx-.005); } unless($sy<=0) { $sy=($sy-.005); } unless($sy<=0) { $sz=($sz-.005); } if($sx<=0) { (@{$o->{position}}) = (0, 0, 0); (@{$o->{scale}}) = (0, 0, 0); (@{$o->{orientation}}) = (0, 0, 0, 0); } (@{$o->{scale}}) = ($sx, $sy, $sz); (@{$o->{position}}) = ($x, $y, $z); glColor(@{$o->{color}}) if $o->{color}; glPushMatrix; glTranslate(@{$o->{position}}) if $o->{position}; glRotate(@{$o->{orientation}}) if $o->{orientation}; glScale(@{$o->{scale}}) if $o->{scale}; $o->{draw}->(); glPopMatrix; glFlush(); } my $floor = $self->{world}{floor}; foreach my $o (@$floor) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); glColor(@{$o->{color}}) if $o->{color}; glPushMatrix; glTranslate(@{$o->{position}}) if $o->{position}; glRotate(@{$o->{orientation}}) if $o->{orientation}; glScale(@{$o->{scale}}) if $o->{scale}; $o->{draw}->(); glPopMatrix; glFlush(); } my $bomb2 = $self->{world}{bomb}; my $falltime=0; my $expospeed=2; my($expogirth, $expoy, $expox, $expoz) = (0, 0, 0, 0); foreach my $o (@$bomb2) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); glColor(@{$o->{color}}) if $o->{color}; glPushMatrix; glTranslate(@{$o->{position}}) if $o->{position}; glRotate(@{$o->{orientation}}) if $o->{orientation}; my ($x, $y, $z) = (@{$o->{position}}); my ($sx, $sy, $sz) = (@{$o->{scale}}); my ($red, $green, $blue) = (@{$o->{color}}); my ($o1, $o2, $o3, $o4) = (@{$o->{orientation}}); # my (%draw) = (@{$o->{draw}}); # print "%draw\n"; # print "$sx, $sy, $sz\n"; # print "$x, $y, $z\n"; # print "$red, $green, $blue\n"; # print "$o1, $o2, $o2, $o4\n"; $falltime++; my $fallspeed = ($falltime*1.5); if($y>1) { # $y=($y-$fallspeed); $y=($y-1); $o1=($o1+5); $o2=($o2+5); $o3=($o3+5); $o3=($o4+5); } if($y<=1) { $falltime=0; $groundcount++; $o1=0; $o2=0; $o3=0; $o4=0; } # the explotion: if(($groundcount>=1)&&($groundcount<20)) { $sx=($sx+4); $sy=($sy+2); $sz=($sz+4); $red=($red+.3); $green=($green+.1); $blue=($blue+.1); $o1=($o1-5); $o2=($o2-5); $o3=($o3-5); $o3=($o4-5); my $fireballcount=0; while($fireballcount<10) { $fireballcount++; my $fireballx = (rand ($sz*3)); my $fireballz = (rand ($sz*3)); my $firebally = (rand ($sz*3)); until($firebally>0) { $firebally=($firebally+5); } push @flames, { lit => 1, color => [ .8, .3, 0], position => [ ($x+$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.5, .5, .5], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ .8, .3, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.5, .5, .5], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ .8, .3, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z-$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.5, .5, .5], draw => \&draw_sphere, }; } $self->{world}{flames} = \@flames; my $objects = $self->{world}{objects}; foreach my $obs (@$objects) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); my ($ox, $oy, $oz) = (@{$obs->{position}}); my ($osx, $osy, $osz) = (@{$obs->{scale}}); $osx = ($osx*6); $osz = ($osz*6); $osy = ($osy*6); if( (($x+$sx)>$ox-$osx)&&(($x-$sx)<$ox+$osx)&&(($z+$sz)>$oz-$osz)&&(($z-$sz)<$oz+$osz)&&($y>$oy-$osy)&&($y<$oy+$osy) ) { # (@{$obs->{scale}}) = (.5, .5, .5); # (@{$obs->{color}}) = (1, 1, 1); (@{$obs->{position}}) = (1, 1, 1); my $fireballcount=0; while($fireballcount<10) { $fireballcount++; my $fireballx = (rand ($sz*5)); my $fireballz = (rand ($sz*5)); my $firebally = (rand ($sz*5)); until($firebally>0) { $firebally=($firebally+5); } push @flames, { lit => 1, color => [ 0, 0, 1], position => [ ($x+$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.25, .25, .25], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ 0, 0, 1], position => [ ($x-$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.25, .25, .25], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ 0, 0, 1], position => [ ($x-$fireballx), ($y+$firebally), ($z-$fireballz)], orientation => [0, 0, 0, 0], scale => [.25, .25, .25], draw => \&draw_sphere, }; } $self->{world}{flames} = \@flames; # $blown="yes"; } } } if($groundcount>=20) { $#flames = -1; $self->{world}{flames} = \@flames; $#bomb = -1; $self->{world}{bomb} = \@bomb; $groundcount=0; } else { (@{$o->{orientation}}) = ($o1, $o2, $o3, $o4); (@{$o->{position}}) = ($x, $y, $z); # (@{$o->{scale}}) = ($sx, $sy, $sz); (@{$o->{color}}) = ($red, $green, $blue); } glScale(@{$o->{scale}}) if $o->{scale}; $o->{draw}->(); glPopMatrix; glFlush(); } my $nuke = $self->{world}{nuke}; my $falltime=0; my $expospeed=2; my($expogirth, $expoy, $expox, $expoz) = (0, 0, 0, 0); foreach my $o (@$nuke) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); glColor(@{$o->{color}}) if $o->{color}; glPushMatrix; glTranslate(@{$o->{position}}) if $o->{position}; glRotate(@{$o->{orientation}}) if $o->{orientation}; my ($x, $y, $z) = (@{$o->{position}}); my ($sx, $sy, $sz) = (@{$o->{scale}}); my ($red, $green, $blue) = (@{$o->{color}}); my ($o1, $o2, $o3, $o4) = (@{$o->{orientation}}); # my (%draw) = (@{$o->{draw}}); # print "%draw\n"; # print "$sx, $sy, $sz\n"; # print "$x, $y, $z\n"; # print "$red, $green, $blue\n"; # print "$o1, $o2, $o2, $o4\n"; $falltime++; my $fallspeed = ($falltime*2.5); if($y>1) { # $y=($y-$fallspeed); $y=($y-.3); $o1=($o1+.25); $o2=($o2+.25); $o3=($o3+.25); $o3=($o4+.25); } if($y<=1) { $falltime=0; $groundcount++; $o1=0; $o2=0; $o3=0; $o4=0; } if($groundcount==2) { push @nukecenter, { lit => 1, color => [ 1, 1, 1], position => [ $x, $y, $z], orientation => [0, 0, 0, 0], scale => [.5, 2, .5], draw => \&draw_sphere, }; $self->{world}{nukecenter} = \@nukecenter; } # the explotion: if(($groundcount>=1)&&($groundcount<50)) { $sx=($sx+4); $sy=($sy+2); $sz=($sz+4); # $red=($red-.3); # $green=($green-.1); # $blue=($blue-.1); $#flames = -1; $self->{world}{flames} = \@flames; my $fireballcount=0; while($fireballcount<400) { $fireballcount++; my $fireballx = (rand ($sx*3)); my $fireballz = (rand ($sz*3)); my $firebally = (rand ($sy*3)); my $firecolorx = (rand 1); my $firecolorz = (rand .9); until($firebally>0) { $firebally=($firebally+5); } push @flames, { lit => 1, color => [ $firecolorx, $firecolorz, 0], position => [ ($x+$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.5, .5, .5], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ $firecolorx, $firecolorz, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.5, .5, .5], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ $firecolorx, $firecolorz, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z-$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.5, .5, .5], draw => \&draw_sphere, }; } $self->{world}{flames} = \@flames; $o1=($o1-5); $o2=($o2-5); $o3=($o3-5); $o3=($o4-5); } if($groundcount>=50) { $#flames = -1; $self->{world}{flames} = \@flames; $#nuke = -1; $self->{world}{nuke} = \@nuke; $#nukecenter = -1; $self->{world}{nukecenter} = \@nukecenter; $groundcount=0; } else { (@{$o->{orientation}}) = ($o1, $o2, $o3, $o4); (@{$o->{position}}) = ($x, $y, $z); (@{$o->{scale}}) = ($sx, $sy, $sz); (@{$o->{color}}) = ($red, $green, $blue); } glScale(@{$o->{scale}}) if $o->{scale}; $o->{draw}->(); glPopMatrix; glFlush(); } # # The Regular Missle's # my $missle = $self->{world}{missle}; my $missle_speed=1; my $expospeed=2; my $blown="no"; foreach my $o (@$missle) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); glColor(@{$o->{color}}) if $o->{color}; glPushMatrix; glTranslate(@{$o->{position}}) if $o->{position}; glRotate(@{$o->{orientation}}) if $o->{orientation}; my ($x, $y, $z) = (@{$o->{position}}); my ($sx, $sy, $sz) = (@{$o->{scale}}); my ($red, $green, $blue) = (@{$o->{color}}); my ($o1, $o2, $o3, $o4) = (@{$o->{orientation}}); if($y>128) { $y=($y-2); $missle_speed=0; } if($y>64) { $y=($y-4); if($y<128) { $sz=2; $missle_speed=4; } } if($y>32) { $y=($y-2); if($y<64) { $sz=4; $missle_speed=6; } } if($y>5) { $y=($y-1); if($y<32) { $sz=6; $missle_speed=8; } $y=($y-.25); } if($y>-1) { # make sure $o1 is between 0 and 360 until($o1<=360) { $o1=($o1-360); } until($o1>0) { $o1=($o1+360); } $missle_speed=($missle_speed+3); # determine missle path my ($zspeed, $xspeed); if(($o1>270)||($o1<90)) { # lower quadrant if($o1>270) { # lower left quadrant $zspeed=(($o1-270)/90); $zspeed=($zspeed*$missle_speed); $z=($z-$zspeed); $xspeed=(($o1-360)/90); $xspeed=($xspeed*$missle_speed); $x=($x-$xspeed); } else { # lower right quadrant $zspeed=(($o1-90)/90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=($o1/90); $xspeed=($xspeed*$missle_speed); $x=($x-$xspeed); } } else { # upper quadrant if($o1>180) { # top left quadrant $zspeed=(($o1-270)/-90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=(($o1-180)/90); $xspeed=($xspeed*$missle_speed); $x=($x+$xspeed); } else { # top right quadrant $zspeed=(($o1-90)/90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=(($o1-180)/90); $xspeed=($xspeed*$missle_speed); $x=($x+$xspeed); } } # $x=($x+($angle3/90)); # $y=($y-.1); } if($y<=5) { my $flamex = (rand 3); my $flamey = (rand 3); my $flamez = (rand 3); push @flames, { lit => 1, color => [ .1, .1, 1], position => [ ($x+$flamex), ($y+$flamey), ($z-$flamez)], orientation => [$o1, $o2, $o3, $o4], scale => [.125, .125, .125], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ 0, 0, .8], position => [ ($x-$flamex), ($y-$flamey), ($z+$flamez)], orientation => [$o1, $o2, $o3, $o4], scale => [.125, .125, .125], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ 0, 0, 1], position => [ ($x-$flamex), ($y-$flamey), ($z-$flamez)], orientation => [$o1, $o2, $o3, $o4], scale => [.125, .125, .125], draw => \&draw_sphere, }; $self->{world}{flames} = \@flames; } my $objects = $self->{world}{objects}; foreach my $obs (@$objects) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); my ($ox, $oy, $oz) = (@{$obs->{position}}); my ($osx, $osy, $osz) = (@{$obs->{scale}}); if( ($x>$ox-$osx)&&($x<$ox+$osx)&&($z>$oz-$osz)&&($z<$oz+$osz)&&($y>$oy-$osy)&&($y<$oy+$osy) ) { # (@{$obs->{scale}}) = (.5, .5, .5); # (@{$obs->{color}}) = (1, 1, 1); (@{$obs->{position}}) = (1, 1, 1); my $fireballcount=0; while($fireballcount<40) { $fireballcount++; my $fireballx = (rand ($sz*3)); my $fireballz = (rand ($sz*3)); my $firebally = (rand ($sz*3)); until($firebally>0) { $firebally=($firebally+5); } push @flames, { lit => 1, color => [ .8, .3, 0], position => [ ($x+$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.25, .25, .25], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ 1, 0, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.25, .25, .25], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ 1, .3, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z-$fireballz)], orientation => [0, 0, 0, 0], scale => [.25, .25, .25], draw => \&draw_sphere, }; } $self->{world}{flames} = \@flames; # $blown="yes"; } } if( ($x>($maxexe+400)) || ($x<-400) || ($z>($maxwhy+400)) || ($z<-400) ) { $y=($y-2); } # make it blow up (when it hits the ground) if( ($y<=-1) || ($blown eq "yes")) { $falltime=0; $groundcount++; } if(($groundcount>=1)&&($groundcount<3.5)) { $sx=($sx+2); $sy=($sy+2); $sz=($sz+2); $red=($red-.1); $green=($green-.1); $blue=($blue-.6); my $fireballcount=0; while($fireballcount<10) { $fireballcount++; my $fireballx = (rand ($sz*3)); my $fireballz = (rand ($sz*3)); my $firebally = (rand ($sz*3)); until($firebally>0) { $firebally=($firebally+5); } push @flames, { lit => 1, color => [ .8, .3, 0], position => [ ($x+$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.5, .5, .5], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ 1, 0, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.5, .5, .5], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ 1, .3, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z-$fireballz)], orientation => [0, 0, 0, 0], scale => [.5, .5, .5], draw => \&draw_sphere, }; } $self->{world}{flames} = \@flames; } if($groundcount>=10) { print "missle's destroyed\n"; $#flames = -1; $self->{world}{flames} = \@flames; $#missle = -1; $self->{world}{missle} = \@missle; $groundcount=0; } else { unless($blown eq "yes") { (@{$o->{position}}) = ($x, $y, $z); } (@{$o->{orientation}}) = ($o1, $o2, $o3, $o4); (@{$o->{scale}}) = ($sx, $sy, $sz); (@{$o->{color}}) = ($red, $green, $blue); } glScale(@{$o->{scale}}) if $o->{scale}; $o->{draw}->(); glPopMatrix; glFlush(); } my $missle2 = $self->{world}{missle2}; my $missle_speed=1; my $expospeed=2; my $o1speed=0; foreach my $o (@$missle2) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); glColor(@{$o->{color}}) if $o->{color}; glPushMatrix; glTranslate(@{$o->{position}}) if $o->{position}; glRotate(@{$o->{orientation}}) if $o->{orientation}; my ($x, $y, $z) = (@{$o->{position}}); my ($sx, $sy, $sz) = (@{$o->{scale}}); my ($red, $green, $blue) = (@{$o->{color}}); my ($o1, $o2, $o3, $o4) = (@{$o->{orientation}}); $o1=($o1+$o1speed); $o3=($o3+$o1speed); $o1speed++; if($o1>360) { $o1=1; } if($o2>360) { $o2=1; } if($y>128) { $y=($y-2); $missle_speed=0; } if($y>64) { $y=($y-1); if($y<128) { $sz=2; my $flamex = (rand 3); my $flamey = (rand 3); my $flamez = (rand 3); push @flames, { lit => 1, color => [ 1, 0, 0], position => [ ($x-$flamex), ($y-$flamey), ($z-$flamez)], orientation => [$o1, $o2, $o3, $o4], scale => [.125, .125, .125], draw => \&draw_sphere, }; $self->{world}{flames} = \@flames; $missle_speed=4; } } if($y>32) { $y=($y-1); if($y<64) { $sz=4; $missle_speed=6; my $flamex = (rand 3); my $flamey = (rand 3); my $flamez = (rand 3); push @flames, { lit => 1, color => [ .8, 1, 0], position => [ ($x+$flamex), ($y+$flamey), ($z-$flamez)], orientation => [$o1, $o2, $o3, $o4], scale => [.125, .125, .125], draw => \&draw_sphere, }; $self->{world}{flames} = \@flames; } } if($y>5) { if($y<32) { $sz=6; my $flamex = (rand 3); my $flamey = (rand 3); my $flamez = (rand 3); push @flames, { lit => 1, color => [ 1, 1, 1], position => [ ($x+$flamex), ($y+$flamey), ($z+$flamez)], orientation => [$o1, $o2, $o3, $o4], scale => [.125, .125, .125], draw => \&draw_sphere, }; $self->{world}{flames} = \@flames; $missle_speed=8; } $y=($y-.25); } if($y>-1) { # make sure $o1 is between 0 and 360 until($o1<=360) { $o1=($o1-360); } until($o1>0) { $o1=($o1+360); } $missle_speed=($missle_speed+3); # determine missle path my ($zspeed, $xspeed); if(($o1>270)||($o1<90)) { # lower quadrant if($o1>270) { # lower left quadrant $zspeed=(($o1-270)/90); $zspeed=($zspeed*$missle_speed); $z=($z-$zspeed); $xspeed=(($o1-360)/90); $xspeed=($xspeed*$missle_speed); $x=($x-$xspeed); } else { # lower right quadrant $zspeed=(($o1-90)/90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=($o1/90); $xspeed=($xspeed*$missle_speed); $x=($x-$xspeed); } } else { # upper quadrant if($o1>180) { # top left quadrant $zspeed=(($o1-270)/-90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=(($o1-180)/90); $xspeed=($xspeed*$missle_speed); $x=($x+$xspeed); } else { # top right quadrant $zspeed=(($o1-90)/90); $zspeed=($zspeed*$missle_speed); $z=($z+$zspeed); $xspeed=(($o1-180)/90); $xspeed=($xspeed*$missle_speed); $x=($x+$xspeed); } } # $x=($x+($angle3/90)); $y=($y-.6); } my $objects = $self->{world}{objects}; foreach my $obs (@$objects) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); my ($ox, $oy, $oz) = (@{$obs->{position}}); my ($osx, $osy, $osz) = (@{$obs->{scale}}); $osx = ($osx*3); $osz = ($osz*3); $osy = ($osy*3); if( ($x>$ox-$osx)&&($x<$ox+$osx)&&($z>$oz-$osz)&&($z<$oz+$osz)&&($y>$oy-$osy)&&($y<$oy+$osy) ) { (@{$obs->{position}}) = (0, 0, 0); my $fireballcount=0; while($fireballcount<10) { $fireballcount++; my $fireballx = (rand ($sz*3)); my $fireballz = (rand ($sz*3)); my $firebally = (rand ($sz*3)); until($firebally>0) { $firebally=($firebally+5); } push @flames, { lit => 1, color => [ .8, .3, 0], position => [ ($x+$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.5, .5, .5], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ 1, 0, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.5, .5, .5], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ 1, .3, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z-$fireballz)], orientation => [0, 0, 0, 0], scale => [.5, .5, .5], draw => \&draw_sphere, }; } $self->{world}{flames} = \@flames; # $blown="yes"; } } # make it blow up (when it hits the ground) if( ($y<=5) || ($x>($maxexe+400)) || ($z>($maxwhy+400)) || ($x<-400) || ($z<-400) ) { $falltime=0; $groundcount++; } if(($groundcount>=1)&&($groundcount<35)) { $sx=($sx+4); $sy=($sy+4); $sz=($sz+4); $red=($red-.1); $green=($green-.1); $blue=($blue-.6); # $#flames = -1; # $self->{world}{flames} = \@flames; my $fireballcount=0; while($fireballcount<15) { $fireballcount++; my $fireballx = (rand ($sx*3)); my $fireballz = (rand ($sz*3)); my $firebally = (rand ($sy*3)); my $firecolorx = (rand 1); my $firecolorz = (rand .3); until($firebally>0) { $firebally=($firebally+5); } push @flames, { lit => 1, color => [ $firecolorx, $firecolorz, 0], position => [ ($x+$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.25, .25, .25], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ $firecolorx, $firecolorz, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z+$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.25, .25, .25], draw => \&draw_sphere, }; push @flames, { lit => 1, color => [ $firecolorx, $firecolorz, 0], position => [ ($x-$fireballx), ($y+$firebally), ($z-$fireballz)], orientation => [$o1, $o2, $o3, $o4], scale => [.25, .25, .25], draw => \&draw_sphere, }; } $self->{world}{flames} = \@flames; } if($groundcount>=35) { $#flames = -1; $self->{world}{flames} = \@flames; $#missle2 = -1; $self->{world}{missle2} = \@missle2; $groundcount=0; } else { (@{$o->{position}}) = ($x, $y, $z); (@{$o->{orientation}}) = ($o1, $o2, $o3, $o4); (@{$o->{scale}}) = ($sx, $sy, $sz); (@{$o->{color}}) = ($red, $green, $blue); } glScale(@{$o->{scale}}) if $o->{scale}; $o->{draw}->(); glPopMatrix; glFlush(); } my $snow = $self->{world}{snow}; my $falltime=0; foreach my $o (@$snow) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); glColor(@{$o->{color}}) if $o->{color}; glPushMatrix; glTranslate(@{$o->{position}}) if $o->{position}; glRotate(@{$o->{orientation}}) if $o->{orientation}; my ($x, $y, $z) = (@{$o->{position}}); my ($sx, $sy, $sz) = (@{$o->{scale}}); $falltime++; # wind change one if(($y>50)&&($y<160)) { $x=($x+$xwind); $z=($z+$zwind); } if(($y>1)&&($y<=50)) { $x=($x+($xwind*2)); $z=($z-($zwind/2)); } if($y>1) { # $y=($y-$fallspeed); $y=($y-.4); $sx=.1; $sz=.1; $sy=.1; } if($y<=1) { $y=($y-.05); $sx=($sx+.05); $sz=($sz+.05); } if($y<.5) { $y=200; $x=(rand $maxexe); $z=(rand $maxwhy); } (@{$o->{position}}) = ($x, $y, $z); (@{$o->{scale}}) = ($sx, $sy, $sz); glScale(@{$o->{scale}}) if $o->{scale}; $o->{draw}->(); glPopMatrix; glFlush(); } my $rain = $self->{world}{rain}; my $falltime=0; foreach my $o (@$rain) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); glColor(@{$o->{color}}) if $o->{color}; glPushMatrix; glTranslate(@{$o->{position}}) if $o->{position}; glRotate(@{$o->{orientation}}) if $o->{orientation}; my ($x, $y, $z) = (@{$o->{position}}); my ($sx, $sy, $sz) = (@{$o->{scale}}); # print "$sx, $sy, $sz\n"; $falltime++; # my $fallspeed = ($falltime*.1); if($y>1) { $y=($y-4); $sx=.125; $sz=.125; $sy=.5; } if($y<=1) { $y=($y-.01); $sx=($sx+.1); $sz=($sz+.1); # $sy=($sy-.4); } if($y<.5) { $sx=.125; $sz=.125; $sy=.25; $y=(rand 100); $y=($y+100); } (@{$o->{position}}) = ($x, $y, $z); (@{$o->{scale}}) = ($sx, $sy, $sz); glScale(@{$o->{scale}}) if $o->{scale}; $o->{draw}->(); glPopMatrix; glFlush(); } my $figure = $self->{world}{figure}; foreach my $o (@$figure) { $o->{lit} ? glEnable (GL_LIGHTING) : glDisable(GL_LIGHTING); glColor(@{$o->{color}}) if $o->{color}; glPushMatrix; glTranslate(@{$o->{position}}) if $o->{position}; glRotate(@{$o->{orientation}}) if $o->{orientation}; glScale(@{$o->{scale}}) if $o->{scale}; $o->{draw}->(); glPopMatrix; glFlush(); } } sub gravity_switch { if($feelgravity eq "on") { $mygravity=0; $feelgravity = "off"; } else { $feelgravity = "on"; # $mygravity=1; } print "Gravity $feelgravity\n"; } sub draw_shape { glBegin(GL_POLYGON); # Front face of pyramid glColor3f(1.0, 0.0, 0.0); # Set the glVertex3f(0.0, 1.0, 0.0); # Top of triangle (front of pyramid) glColor3f(0.0, 1.0, 0.0); # Set the color to green glVertex3f(-1.0, -1.0, 1.0); # Left of triangle (front of pyramid) glColor3f(0.0, 0.0, 1.0); # Set the color to blue glVertex3f(1.0, -1.0, 1.0); # Right of traingle (front of pyramid) # Right face of pyramid glColor3f(1.0, 0.0, 0.0); # Red color glVertex3f(0.0, 1.0, 0.0); # Top of triangle (right of pyramid) glColor3f(0.0, 0.0, 1.0); # Blue color glVertex3f(1.0, -1.0, 1.0); # Left of triangle (right of pyramid) glColor3f(0.0, 1.0, 0.0); # Green color glVertex3f(1.0, -1.0, -1.0); # Right of triangle (right of pyramid) # Back face of pyramid glColor3f(1.0, 0.0, 0.0); # Red color glVertex3f(0.0, 1.0, 0.0); # Top of triangle (back of pyramid) glColor3f(0.0, 1.0, 0.0); # Green color glVertex3f(1.0, -1.0, -1.0); # Left of triangle (back of pyramid) glColor3f(0.0, 0.0, 1.0); # Blue color glVertex3f(-1.0, -1.0, -1.0); # Right of triangle (back of pyramid) # Left face of pyramid. glColor3f(1.0, 0.0, 0.0); # Red color glVertex3f(0.0, 1.0, 0.0); # Top of triangle (left of pyramid) glColor3f(0.0, 0.0, 1.0); # Blue color glVertex3f(-1.0, -1.0, -1.0); # Left of triangle (left of pyramid) glColor3f(0.0, 1.0, 0.0); # Green color glVertex3f(-1.0, -1.0, 1.0); # Right of triangle (left of pyramid) # Done with the polygon glEnd; } sub draw_house { glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex3f(1.0, 1.0, 1.0); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, -1.0); glColor3f(1.0, 0.0, 0.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, 1.0); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glColor3f(1.0, 0.0, 0.0); glVertex3f(-1.0, 1.0, 1.0); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0); glColor3f(1.0, 0.0, 0.0); glVertex3f(-1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(-1.0, 1.0, -1.0); glColor3f(0.0, 0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, 1.0); # Done with the polygon glEnd; } sub draw_tree { glBegin(GL_POLYGON); # stump glColor3f(0.1, .1, 0); glVertex3f(0.3, -0.5, 0.3); glVertex3f(0.3, -1.0, 0.3); glVertex3f(0.3, -1.0, -0.3); glVertex3f(0.3, -0.5, -0.3); glVertex3f(0.3, -0.5, 0.3); glVertex3f(0.3, -0.5, 0.3); glVertex3f(-0.3, -0.5, 0.3); glVertex3f(-0.3, -0.5, -0.3); glVertex3f(0.3, -0.5, -0.3); glVertex3f(0.3, -0.5, 0.3); glVertex3f(0.3, -1.0, 0.3); glVertex3f(-0.3, -1.0, 0.3); glVertex3f(-0.3, -0.5, 0.3); glVertex3f(0.3, -1.0, 0.3); glVertex3f(-0.3, -1.0, 0.3); glVertex3f(-0.3, -1.0, -0.3); glVertex3f(-0.3, -0.5, -0.3); glVertex3f(0.3, -0.5, -0.3); glVertex3f(-0.3, -0.5, -0.3); glVertex3f(-0.3, -1.0, -0.3); glVertex3f(0.3, -1.0, -0.3); glVertex3f(0.3, -1.0, 0.3); glColor3f(0.0, 1.0, 0.0); glVertex3f(0.0, 0.0, 0.0); # leaves # Front face of the tre glColor3f(0.0, 1.0, 0.0); glVertex3f(0.0, 1.0, 0.0); glColor3f(0.0, 0.0, 0.0); glVertex3f(-1.0, -0.5, 1.0); glVertex3f(1.0, -0.5, 1.0); # Right face of pyramid glColor3f(0.0, 0.7, 0.0); glVertex3f(0.0, 1.0, 0.0); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -0.5, 1.0); glVertex3f(1.0, -0.5, -1.0); # Back face of pyramid glColor3f(0.0, 1.0, 0.0); glVertex3f(0.0, 1.0, 0.0); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -0.5, -1.0); glVertex3f(-1.0, -0.5, -1.0); # Left face of pyramid. glColor3f(0.0, 1.5, 0.0); glVertex3f(0.0, 1.0, 0.0); glColor3f(0.0, 0.0, 0.0); glVertex3f(-1.0, -0.5, -1.0); glVertex3f(-1.0, -0.5, 1.0); # Done with the polygon glEnd; } sub draw_mp3 { glBegin(GL_POLYGON); # Front face of cube glColor3f(0.3, 0.1, 0.0); glVertex3f(.8, 2.5, .8); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, -1.0); glColor3f(0.3, 0.1, 0.0); glVertex3f(.8, 2.5, -.8); glVertex3f(.8, 2.5, .8); glVertex3f(.8, 2.5, .8); glVertex3f(-.8, 2.5, .8); glVertex3f(-.8, 2.5, -.8); glVertex3f(.8, 2.5, -.8); glVertex3f(.8, 2.5, .8); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glColor3f(0.3, 0.1, 0.0); glVertex3f(-.8, 2.5, .8); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0); glColor3f(0.3, 0.1, 0.0); glVertex3f(-.8, 2.5, -.8); glVertex3f(.8, 2.5, -.8); glVertex3f(-.8, 2.5, -.8); glColor3f(0.0, 0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, 1.0); # top peice glColor3f(0.3, 0.1, 0.0); glVertex3f(.0, 3.5, .0); glColor3f(0.0, 0.0, 0.0); glVertex3f(.8, 2.5, .8); glVertex3f(.8, 2.5, -.8); glColor3f(0.3, 0.1, 0.0); glVertex3f(.0, 3.5, .0); glColor3f(0.0, 0.0, 0.0); glVertex3f(.8, 2.5, .8); glVertex3f(-.8, 2.5, .8); glColor3f(0.3, 0.1, 0.0); glVertex3f(.0, 3.5, .0); glColor3f(0.0, 0.0, 0.0); glVertex3f(.8, 2.5, .8); glVertex3f(-.8, 2.5, .8); glVertex3f(-.8, 2.5, -.8); glColor3f(0.3, 0.1, 0.0); glVertex3f(.0, 3.5, .0); glVertex3f(.0, 3.5, .0); glVertex3f(.0, 3.5, .0); glColor3f(0.0, 0.0, 0.0); glVertex3f(-.8, 2.5, -.8); glVertex3f(.8, 2.5, -.8); glVertex3f(.8, 2.5, .8); glEnd; } sub draw_sky_scraper { glBegin(GL_POLYGON); # Front face of cube glColor3f(0.3, 0.1, 0.0); glVertex3f(.8, 2.5, .8); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, -1.0); glColor3f(0.3, 0.1, 0.0); glVertex3f(.8, 2.5, -.8); glVertex3f(.8, 2.5, .8); glVertex3f(.8, 2.5, .8); glVertex3f(-.8, 2.5, .8); glVertex3f(-.8, 2.5, -.8); glVertex3f(.8, 2.5, -.8); glVertex3f(.8, 2.5, .8); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glColor3f(0.3, 0.1, 0.0); glVertex3f(-.8, 2.5, .8); glColor3f(0.0, 0.0, 0.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0); glColor3f(0.3, 0.1, 0.0); glVertex3f(-.8, 2.5, -.8); glVertex3f(.8, 2.5, -.8); glVertex3f(-.8, 2.5, -.8); glColor3f(0.0, 0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, 1.0); # top peice glColor3f(0.3, 0.1, 0.0); glVertex3f(.0, 3.5, .0); glColor3f(0.0, 0.0, 0.0); glVertex3f(.8, 2.5, .8); glVertex3f(.8, 2.5, -.8); glColor3f(0.3, 0.1, 0.0); glVertex3f(.0, 3.5, .0); glColor3f(0.0, 0.0, 0.0); glVertex3f(.8, 2.5, .8); glVertex3f(-.8, 2.5, .8); glColor3f(0.3, 0.1, 0.0); glVertex3f(.0, 3.5, .0); glColor3f(0.0, 0.0, 0.0); glVertex3f(.8, 2.5, .8); glVertex3f(-.8, 2.5, .8); glVertex3f(-.8, 2.5, -.8); glColor3f(0.3, 0.1, 0.0); glVertex3f(.0, 3.5, .0); glVertex3f(.0, 3.5, .0); glVertex3f(.0, 3.5, .0); glColor3f(0.0, 0.0, 0.0); glVertex3f(-.8, 2.5, -.8); glVertex3f(.8, 2.5, -.8); glVertex3f(.8, 2.5, .8); glEnd; } sub draw_sphere { use OpenGL ':old', ':glutfunctions'; glBegin(GL_POLYGON); glutSolidSphere(5,8,5); # $rot=($rot+.1); # Rotate($rot, 1,3,3); glPushMatrix(); # Done with the polygon glEnd; } sub draw_floor_sphere { use OpenGL ':old', ':glutfunctions'; glBegin(GL_POLYGON); glutSolidSphere(5,8,5); glPushMatrix(); # Done with the polygon glEnd; } sub draw_figure { use OpenGL ':old', ':glutfunctions'; glBegin(GL_POLYGON); glutSolidSphere(2.5,32,32); glPushMatrix(); glEnd; } sub draw_house2 { glBegin(GL_POLYGON); glColor3f(0.9, 0.9, 0.9); glVertex3f(1.0, .7, 1.0); glColor3f(0.1, 0.1, 0.1); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, -1.0); glColor3f(0.9, 0.9, 0.9); glVertex3f(1.0, .7, -1.0); glVertex3f(1.0, .7, 1.0); glVertex3f(1.0, .7, 1.0); glVertex3f(-1.0, .7, 1.0); glVertex3f(-1.0, .7, -1.0); glVertex3f(1.0, .7, -1.0); glVertex3f(1.0, .7, 1.0); glColor3f(.1, .1, .1); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glColor3f(.9, .9, .9); glVertex3f(-1.0, .7, 1.0); glColor3f(.1, .1, .1); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0); glColor3f(.9, .9, .9); glVertex3f(-1.0, .7, -1.0); glVertex3f(1.0, .7, -1.0); glVertex3f(-1.0, .7, -1.0); glColor3f(.1, .1, .1); glVertex3f(-1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, .7, 1.0); # the roof glColor3f(.1, .1, 1.3); glVertex3f(1.0, .7, 1.0); glVertex3f(-1.0, .7, 1.0); glVertex3f(-1.0, 1.0, .0); glVertex3f(1.0, 1.0, .0); glVertex3f(1.0, .7, -1.0); glVertex3f(-1.0, .7, -1.0); glVertex3f(-1.0, 1.0, .0); glVertex3f(1.0, 1.0, .0); glVertex3f(1.0, .7, 1.0); # Done with the polygon glEnd; } sub draw_house3 { glBegin(GL_POLYGON); glColor3f(0.5, 0.9, 0.9); glVertex3f(1.0, .7, 1.0); glColor3f(0.1, 0.1, 0.1); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, -1.0); glColor3f(0.7, 0.2, 0.7); glVertex3f(1.0, .7, -1.0); glVertex3f(1.0, .7, 1.0); glVertex3f(1.0, .7, 1.0); glVertex3f(-1.0, .7, 1.0); glVertex3f(-1.0, .7, -1.0); glVertex3f(1.0, .7, -1.0); glVertex3f(1.0, .7, 1.0); glColor3f(0.1, 0.1, 0.1); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glColor3f(0.7, 0.2, 0.7); glVertex3f(-1.0, .7, 1.0); glColor3f(0.1, 0.1, 0.1); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0); glColor3f(0.7, 0.2, 0.7); glVertex3f(-1.0, .7, -1.0); glVertex3f(1.0, .7, -1.0); glVertex3f(-1.0, .7, -1.0); glColor3f(0.1, 0.1, 0.1); glVertex3f(-1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, .7, 1.0); # Done with the polygon glEnd; } sub draw_trash_can { glBegin(GL_POLYGON); glColor3f(0.9, 0.9, 0.9); glVertex3f(1.0, .7, 1.0); glColor3f(0.1, 0.1, 0.1); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, -1.0); glColor3f(0.9, 0.9, 0.9); glVertex3f(1.0, .7, -1.0); glVertex3f(1.0, .7, 1.0); glVertex3f(1.0, .7, 1.0); glVertex3f(-1.0, .7, 1.0); glVertex3f(-1.0, .7, -1.0); glVertex3f(1.0, .7, -1.0); glVertex3f(1.0, .7, 1.0); glColor3f(.1, .1, .1); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glColor3f(.9, .9, .9); glVertex3f(-1.0, .7, 1.0); glColor3f(.1, .1, .1); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0); glColor3f(.9, .9, .9); glVertex3f(-1.0, .7, -1.0); glVertex3f(1.0, .7, -1.0); glVertex3f(-1.0, .7, -1.0); glColor3f(.1, .1, .1); glVertex3f(-1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, .7, 1.0); # the roof glColor3f(.0, .0, .0); glVertex3f(1.0, .7, 1.0); glVertex3f(-1.0, .7, 1.0); glVertex3f(-1.0, 1.5, -1.0); glVertex3f(1.0, 1.5, -1.0); # Done with the polygon glEnd; } sub draw_stop_sign { glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex3f(0.5, 1.0, 0.0); glVertex3f(1.0, 0.5, 0.0); glVertex3f(1.0, -0.5, 0.0); glVertex3f(0.5, -1.0, 0.0); glVertex3f(-0.5, -1.0, 0.0); glVertex3f(-1.0, -0.5, 0.0); glVertex3f(-1.0, 0.5, 0.0); glVertex3f(-0.5, 1.0, 0.0); glVertex3f(0.5, 1.0, 0.0); glEnd; glBegin(GL_POLYGON); glColor3f(0.4, 0.4, 0.4); glVertex3f(0.0, -1.0, 0.0); glVertex3f(-0.2, -1.0, 0.0); glVertex3f(-0.2, -3.0, 0.0); glVertex3f(0.1, -3.0, 0.0); glVertex3f(0.1, -1.0, 0.0); # Done with the polygon glEnd; } sub draw_cube { glBegin(GL_POLYGON); # Front face of cube glVertex3f(1.0, 1.0, 1.0); # {front) glVertex3f(1.0, -1.0, 1.0); # (front) glVertex3f(1.0, -1.0, -1.0); # (front) glVertex3f(1.0, 1.0, -1.0); # (front) glVertex3f(1.0, 1.0, 1.0); # (front) glVertex3f(1.0, 1.0, 1.0); # (top) glVertex3f(-1.0, 1.0, 1.0); # (top) glVertex3f(-1.0, 1.0, -1.0); # (top) glVertex3f(1.0, 1.0, -1.0); # (top) glVertex3f(1.0, 1.0, 1.0); # (left side) glVertex3f(1.0, -1.0, 1.0); # (left side) glVertex3f(-1.0, -1.0, 1.0); # (left side) glVertex3f(-1.0, 1.0, 1.0); # (left side) glVertex3f(1.0, -1.0, 1.0); # (left side) glVertex3f(-1.0, -1.0, 1.0); # (back side) glVertex3f(-1.0, -1.0, -1.0); # (back side) glVertex3f(-1.0, 1.0, -1.0); # (back side) glVertex3f(1.0, 1.0, -1.0); # (back side) glVertex3f(-1.0, 1.0, -1.0); # (right side) glVertex3f(-1.0, -1.0, -1.0); # (right side) glVertex3f(1.0, -1.0, -1.0); # (right side) glVertex3f(1.0, -1.0, 1.0); # (right side) # glRotate3f(.1,0,1,0); # Done with the polygon glEnd; } sub draw_cube2 { # A simple cube my @indices = qw( 4 5 6 7 1 2 6 5 0 1 5 4 0 3 2 1 0 4 7 3 2 3 7 6 ); my @vertices = ([-1, -1, -1], [ 1, -1, -1], [ 1, 1, -1], [-1, 1, -1], [-1, -1, 1], [ 1, -1, 1], [ 1, 1, 1], [-1, 1, 1]); my @normals = ([0, 0, 1], [ 1, 0, 0], [0, -1, 0], [0, 0, -1], [-1, 0, 0], [0, 1, 0]); foreach my $face (0 .. 5) { my $normal = $normals[$face]; my @corners; foreach my $vertex (0 .. 3) { my $index = $indices[4 * $face + $vertex]; my $coords = $vertices[$index]; push @corners, $coords; } draw_quad_face(normal => $normal, corners => \@corners); } } sub draw_quad_face { my %args = @_; my $normal = $args{normal}; my $corners = $args{corners}; my $div = $args{divisions} || 10; my ($a, $b, $c, $d) = @$corners; # NOTE: ASSUMES FACE IS A PARALLELOGRAM my $s_ab = calc_vector_step($a, $b, $div); my $s_ad = calc_vector_step($a, $d, $div); glNormal(@$normal); for my $strip (0 .. $div - 1) { my @v = ($a->[0] + $strip * $s_ab->[0], $a->[1] + $strip * $s_ab->[1], $a->[2] + $strip * $s_ab->[2]); glBegin(GL_QUAD_STRIP); for my $quad (0 .. $div) { glVertex(@v); glVertex($v[0] + $s_ab->[0], $v[1] + $s_ab->[1], $v[2] + $s_ab->[2]); $v[0] += $s_ad->[0]; $v[1] += $s_ad->[1]; $v[2] += $s_ad->[2]; } glEnd; } } sub calc_vector_step { my ($v1, $v2, $div) = @_; return [($v2->[0] - $v1->[0]) / $div, ($v2->[1] - $v1->[1]) / $div, ($v2->[2] - $v1->[2]) / $div]; } sub draw_missle { glBegin(GL_POLYGON); # Front face of cube glVertex3f(1.0, 1.0, 1.0); # {front) glVertex3f(1.0, -1.0, 1.0); # (front) glVertex3f(1.0, -1.0, -1.0); # (front) glVertex3f(1.0, 1.0, -1.0); # (front) glVertex3f(1.0, 1.0, 1.0); # (front) glVertex3f(1.0, 1.0, 1.0); # (top) glVertex3f(-1.0, 1.0, 1.0); # (top) glVertex3f(-1.0, 1.0, -1.0); # (top) glVertex3f(1.0, 1.0, -1.0); # (top) glVertex3f(1.0, 1.0, 1.0); # (left side) glVertex3f(1.0, -1.0, 1.0); # (left side) glVertex3f(-1.0, -1.0, 1.0); # (left side) glVertex3f(-1.0, 1.0, 1.0); # (left side) glVertex3f(1.0, -1.0, 1.0); # (left side) glVertex3f(-1.0, -1.0, 1.0); # (back side) glVertex3f(-1.0, -1.0, -1.0); # (back side) glVertex3f(-1.0, 1.0, -1.0); # (back side) glVertex3f(1.0, 1.0, -1.0); # (back side) glVertex3f(-1.0, 1.0, -1.0); # (right side) glVertex3f(-1.0, -1.0, -1.0); # (right side) glVertex3f(1.0, -1.0, -1.0); # (right side) glVertex3f(1.0, -1.0, 1.0); # (right side) # Done with the polygon glEnd; } sub draw_device { glBegin(GL_POLYGON); # Front face of cube glVertex3f(1.0, 1.0, 1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0); glVertex3f(-1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(-1.0, 1.0, -1.0); glVertex3f(-1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, 1.0); # Done with the polygon glEnd; } #sub draw_image #{ ## my $self = shift; ## $self->prep_frame; # my $file = "stan.ppm"; # -r $file or $file = "/home/elliot/$file"; # glpReadTex($file); # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); # if ($pollution eq "on") { # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); # } # glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); # glEnable(GL_TEXTURE_2D); # glBegin(GL_QUADS); # glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0); # glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 0.0); # glTexCoord2f(1.0, 0.0); glVertex3f(1.0, 1.0, 0.0); # glTexCoord2f(1.0, 1.0); glVertex3f(1.0, -1.0, 0.0); # glTexCoord2f(1.0, 1.0); glVertex3f(1.0, -1.0, 0.0); # glEnd; #} #sub draw_door #{ # my $self = shift; # $self->prep_frame; # my $file = "door.ppm"; # -r $file or $file = "/home/elliot/$file"; # glpReadTex($file); # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); # glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); # glEnable(GL_TEXTURE_2D); # glBegin(GL_QUADS); # glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0); # glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 0.0); # glTexCoord2f(1.0, 0.0); glVertex3f(1.0, 1.0, 0.0); # glTexCoord2f(1.0, 1.0); glVertex3f(1.0, -1.0, 0.0); # glTexCoord2f(1.0, 1.0); glVertex3f(1.0, -1.0, 0.0); # glEnd; #} sub draw_pentagon { # my $downcolor ="0.2, 0.5, 0.0"; # my $upcolor ="0.0, 0.0, 0.0"; glBegin(GL_POLYGON); # Front face of cube glColor3f(0.0, 0.0, 0.0); # middle of structure glVertex3f(.5, 1.5, .5); glVertex3f(.5, -1.0, .5); glVertex3f(.5, -1.0, -.5); glColor3f(0.7, 0.0, 0.0); glVertex3f(.5, 1.5, -.5); glVertex3f(.5, 1.5, .5); glVertex3f(.5, 1.5, .5); glVertex3f(-.5, 1.5, .5); glVertex3f(-.5, 1.5, -.5); glVertex3f(.5, 1.5, -.5); glVertex3f(.5, 1.5, .5); glColor3f(0.0, 0.0, 0.0); glVertex3f(.5, -1.0, .5); glVertex3f(-.5, -1.0, .5); glColor3f(0.7, 0.0, 0.0); glVertex3f(-.5, 1.5, .5); glColor3f(0.0, 0.0, 0.0); glVertex3f(.5, -1.0, .5); glVertex3f(-.5, -1.0, .5); glVertex3f(-.5, -1.0, -.5); glColor3f(0.7, 0.0, 0.0); glVertex3f(-.5, 1.5, -.5); glVertex3f(.5, 1.5, -.5); glVertex3f(-.5, 1.5, -.5); glColor3f(0.0, 0.0, 0.0); glVertex3f(-.5, -1.0, -.5); glVertex3f(.5, -1.0, -.5); glVertex3f(.5, -1.0, .5); glColor3f(0.7, 0.0, 0.0); glVertex3f(.5, 1.0, .5); glVertex3f(-.5, 1.0, .5); glVertex3f(-.5, 1.0, -.5); glVertex3f(-.5, 1.0, 2.5); glVertex3f(1.5, 1.0, 2.5); # Done with the polygon glEnd; } sub delay { my $seconds = shift; SDL::Delay($seconds * 20); } sub end_frame { my $self = shift; $self->{resource}{sdl_app}->sync; $self->screenshot if $self->{state}{need_screenshot}; } sub screenshot { use OpenGL; use File::Basename; use SDL::App; use SDL::Constants; use SDL::Event; use SDL::OpenGL; use Math::Complex; my $self = shift; $piccount++; my $file = basename($0) . ".$piccount.bmp"; my $w = $self->{conf}{width}; my $h = $self->{conf}{height}; glReadBuffer(GL_FRONT); my $data = glReadPixels(0, 0, $w, $h, GL_BGR, GL_UNSIGNED_BYTE); SDL::OpenGL::SaveBMP($file, $w, $h, 24, $data); $self->{state}{need_screenshot} = 0; } sub cleanup { print "\nDone.\n" }