#C:\Perl\bin\perl -w $TRAHeader = "\013Rod'sTracer"; $curver = 0x00010001; #$curver = 101; %OBJID = ('obj_sphere',0,'light_omni',1,'viewport',2,'ambient',3,'obj_plane',4, 'null',5,'camera',6,'tri_plane',7,'tri',8,'quad',9,'translate',10, 'rotate',11,'scale',12); %COLOR = ('R',0.5,'G',0.5,'B',0.5); %SURFACE = ('Kd',0.6,'Ks',0.6,'Ns',3); %AMB = ('R',0.3,'G',0.2,'B',0.1); #------------------------------------------- @vertex = (); @faces = (); %procs = ( 0x3d3d => \&EDIT3DS, 0x4000 => \&EDIT_OBJECT, 0x4100 => \&OBJ_TRIMESH, 0x4110 => \&TRI_VERTEXL, 0x4120 => \&TRI_FACEL, 0x4700 => \&OBJ_CAMERA ); #------------------------------------------- $C = 0; $ObjName = ""; $CHUNK_MAIN = 0; $CHUNK = 0; $CLEN = 0; $POS = 6; $GLEN = 0; if (@ARGV < 1 ) { die "Usage: 3ds2tra.pl [outfile.tra]\n"; } if (!-f $ARGV[0]) { die "Error opening $ARGV[0]\n"; } $INname = $ARGV[0]; $ARGV[0] =~ /(.+)\../; $OUTname = $1.'.tra'; if (defined $ARGV[1]) { $OUTname = $ARGV[1] } open IN, "<$INname" || die "Error opening $INname:$!\n"; binmode IN; open OUT, ">$OUTname" || die "Error opening $OUTname:$!\n"; binmode OUT; print OUT $TRAHeader; print OUT pack('L',$curver); print OUT pack('C',$OBJID{'ambient'}); saveRGB(%AMB); read IN, $C, 2; $CHUNK_MAIN = unpack "S", $C; ($CHUNK_MAIN == 0x4d4d) || die "Not a 3ds file\n"; read IN, $C, 4; $GLEN = unpack "L", $C; printf "0x%x\n",$GLEN; while (!eof(IN) && ($POS < $GLEN)) { (read(IN,$C,2)==2) || die "Unexpected EOF reading chunk\n"; $CHUNK = unpack "S", $C; (read(IN,$C,4)==4) || die "Unexpected EOF reading chunk lenght\n"; $CLEN = unpack "L", $C; die "Chunk size error" if $CLEN == 0; if ($procs{$CHUNK}) { $POS += $procs{$CHUNK}->()+6; } else { $POS += $CLEN; } seek IN, $POS, SEEK_SET; } foreach $face (@faces) { print OUT pack("C",$OBJID{'tri'},1); saveVec($vertex[$face->{'v1'}]); saveVec($vertex[$face->{'v2'}]); saveVec($vertex[$face->{'v3'}]); saveRGB(%COLOR); saveSurf(%SURFACE); } @faces = (); @vertex = (); sub saveVec { my ($vec) = @_; print OUT pack("d3",$$vec{'X'},$$vec{'Y'},$$vec{'Z'}); }; sub saveRGB { my (%vec) = @_; print OUT pack("d3",$vec{'R'},$vec{'G'},$vec{'B'}); }; sub saveSurf { my (%vec) = @_; print OUT pack("d3",$vec{'Kd'},$vec{'Ks'},$vec{'Ns'}); }; sub saveDouble { my ($val) = @_; print OUT pack("d",$val); }; sub EDIT3DS { print "Loading Edit\n"; return 0; } sub EDIT_OBJECT { $ObjName = ""; { read (IN, $C, 1); last if $C eq "\0"; $ObjName .= $C; redo; } print "Loaded $ObjName\n"; return length($ObjName)+1; } sub OBJ_TRIMESH { print "Loading Trimesh ($ObjName)\n"; foreach $face (@faces) { print "writing !\n"; print OUT pack("C",$OBJID{'tri'},1); saveVec($vertex[$face->{'v1'}]); saveVec($vertex[$face->{'v2'}]); saveVec($vertex[$face->{'v3'}]); saveRGB($COLOR); saveSurf($SURFACE); } @faces = (); @vertex = (); return 0; } sub TRI_VERTEXL { my ($count,$i); read IN,$C,2; $count = unpack "S", $C; print "Loading $count vertexes\n"; for ($i=0;$i<$count;$i++) { read IN, $C ,4; $vertex[$i]->{'X'} = unpack "f", $C; read IN, $C ,4; $vertex[$i]->{'Z'} = unpack "f", $C; read IN, $C,4; $vertex[$i]->{'Y'} = unpack "f", $C; } return $count*12+2; } sub TRI_FACEL { my ($count,$i,$tmp); read IN,$C,2; $count = unpack "S", $C; print "Loading $count faces\n"; for ($i=0;$i<$count;$i++) { read IN, $C ,2; $faces[$i]->{'v1'} = unpack "S",$C; read IN, $C ,2; $faces[$i]->{'v2'} = unpack "S",$C; read IN, $C ,2; $faces[$i]->{'v3'} = unpack "S",$C; read IN,$tmp,2 } return $count*8+2; } sub OBJ_CAMERA { my (%org,%targ,$roll,$fov,$xtoy); $xtoy = 1; print "Loading Camera ($ObjName)\n"; read IN, $C ,4; $org{'X'} = unpack "f", $C; read IN, $C ,4; $org{'Z'} = unpack "f", $C; read IN, $C,4; $org{'Y'} = unpack "f", $C; print "Origin - $org{'X'}:$org{'Y'}:$org{'Z'}\n"; read IN, $C ,4; $targ{'X'} = unpack "f", $C; read IN, $C ,4; $targ{'Z'} = unpack "f", $C; read IN, $C,4; $targ{'Y'} = unpack "f", $C; print "Target - $targ{'X'}:$targ{'Y'}:$targ{'Z'}\n"; read IN, $C ,4; $roll = unpack "f", $C; read IN, $C ,4; $fov = unpack "f", $C; print "Roll,Fov - $roll,$fov\n"; #---------------------------------- print OUT pack "C", $OBJID{'camera'}; saveVec(\%org); saveVec(\%targ); saveDouble($roll); saveDouble($fov); saveDouble($xtoy); return 32; }