#!/usr/bin/perl -w ####################################### # ms3d.pm # perl 5 ############# # my small 3d engine # # ###################################### use strict; use warnings; package prj::ms3d; use Tk; use Tk::Canvas; sub new { my $this = shift; my $thisref = ref($this) || $this; my $self = undef; my $parentwin = $_[0]; $self->{width} = $_[1]; $self->{height} = $_[2]; $self->{tris} = undef; $self->{cnt} = 0; $self->{canvas} = $parentwin->Canvas(-height => $self->{height}, -width => $self->{width})->pack(); bless ($self, $thisref); } sub addTriangle { my $self = shift; push (@{$self->{tris}}, \@_); $self->{cnt}++; } sub translate { my $self = shift; my $tx = $_[0]; my $ty = $_[1]; my $tz = $_[2]; my @tridata; for (my $i = 0; $i <$self->{cnt}; $i++) { my @data = @{$self->{tris}[$i]}; $data[0] += $tx; $data[1] += $ty; $data[2] += $tz; $data[3] += $tx; $data[4] += $ty; $data[5] += $tz; $data[6] += $tx; $data[7] += $ty; $data[8] += $tz; ${$self->{tris}}[$i] = \@data; } } sub scale { my $self = shift; my $tx = $_[0]; my $ty = $_[1]; my $tz = $_[2]; if ($tx == 0){ $tx = 1; } if ($ty == 0){ $ty = 1; } if ($tz == 0){ $tz = 1; } my @tridata; for (my $i = 0; $i <$self->{cnt}; $i++) { my @data = @{$self->{tris}[$i]}; $data[0] *= $tx; $data[1] *= $ty; $data[2] *= $tz; $data[3] *= $tx; $data[4] *= $ty; $data[5] *= $tz; $data[6] *= $tx; $data[7] *= $ty; $data[8] *= $tz; ${$self->{tris}}[$i] = \@data; } } sub rotate { my $self = shift; my $dir = $_[0]; my $alpha = $_[1]; my $sinal = sin(3.14 * ($alpha / 180)); my $cosal = cos(3.14 * ($alpha / 180)); for (my $i = 0; $i <$self->{cnt}; $i++) { my @data = @{$self->{tris}[$i]}; if ($dir eq 'x') { $data[0] = $data[0]; $data[1] = $data[1] * $cosal - $data[3] * $sinal; $data[2] = $data[1] * $sinal + $data[3] * $cosal; $data[3] = $data[3]; $data[4] = $data[4] * $cosal - $data[5] * $sinal; $data[5] = $data[4] * $sinal + $data[5] * $cosal; $data[6] = $data[6]; $data[7] = $data[7] * $cosal - $data[8] * $sinal; $data[8] = $data[7] * $sinal + $data[8] * $cosal; } elsif ($dir eq 'y') { $data[0] = $data[2] * $sinal + $data[0] * $cosal; $data[1] = $data[1]; $data[2] = $data[2] * $cosal - $data[0] * $sinal; $data[3] = $data[5] * $sinal + $data[3] * $cosal; $data[4] = $data[4]; $data[5] = $data[5] * $cosal - $data[3] * $sinal; $data[6] = $data[8] * $sinal + $data[6] * $cosal; $data[7] = $data[7]; $data[8] = $data[8] * $cosal - $data[6] * $sinal; } elsif ($dir eq 'z') { $data[0] = $data[0] * $cosal - $data[1] * $sinal; $data[1] = $data[0] * $sinal + $data[1] * $cosal; $data[2] = $data[2]; $data[3] = $data[3] * $cosal - $data[4] * $sinal; $data[4] = $data[3] * $sinal + $data[4] * $cosal; $data[5] = $data[5]; $data[6] = $data[6] * $cosal - $data[7] * $sinal; $data[7] = $data[6] * $sinal + $data[7] * $cosal; $data[8] = $data[8]; } ${$self->{tris}}[$i] = \@data; } } sub redraw { my $self = shift; my @vdt = undef; my $dhh = $self->{height} / 2; my $dwh = $self->{width} / 2; foreach my $tridata (@{$self->{tris}}) { @vdt = @$tridata; $self->{canvas}->createPolygon ( $self->calc3d ($vdt[0], $vdt[2]) * $dwh, $self->calc3d ($vdt[1], $vdt[2]) * $dhh, $self->calc3d ($vdt[3], $vdt[5]) * $dwh, $self->calc3d ($vdt[4], $vdt[5]) * $dhh, $self->calc3d ($vdt[6], $vdt[8]) * $dwh, $self->calc3d ($vdt[7], $vdt[8]) * $dhh, -outline =>$vdt[9], -fill =>$vdt[9] ); } } sub calc3d { my $self = shift; my $erg = $_[0] / $_[1] + 0.5; return $erg; } return 1;