3ds2tra.pl 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #C:\Perl\bin\perl -w
  2. $TRAHeader = "\013Rod'sTracer";
  3. $curver = 0x00010001;
  4. #$curver = 101;
  5. %OBJID = ('obj_sphere',0,'light_omni',1,'viewport',2,'ambient',3,'obj_plane',4,
  6. 'null',5,'camera',6,'tri_plane',7,'tri',8,'quad',9,'translate',10,
  7. 'rotate',11,'scale',12);
  8. %COLOR = ('R',0.5,'G',0.5,'B',0.5);
  9. %SURFACE = ('Kd',0.6,'Ks',0.6,'Ns',3);
  10. %AMB = ('R',0.3,'G',0.2,'B',0.1);
  11. #-------------------------------------------
  12. @vertex = ();
  13. @faces = ();
  14. %procs = (
  15. 0x3d3d => \&EDIT3DS,
  16. 0x4000 => \&EDIT_OBJECT,
  17. 0x4100 => \&OBJ_TRIMESH,
  18. 0x4110 => \&TRI_VERTEXL,
  19. 0x4120 => \&TRI_FACEL,
  20. 0x4700 => \&OBJ_CAMERA
  21. );
  22. #-------------------------------------------
  23. $C = 0;
  24. $ObjName = "";
  25. $CHUNK_MAIN = 0;
  26. $CHUNK = 0;
  27. $CLEN = 0;
  28. $POS = 6;
  29. $GLEN = 0;
  30. if (@ARGV < 1 )
  31. {
  32. die "Usage: 3ds2tra.pl <infile.3ds> [outfile.tra]\n";
  33. }
  34. if (!-f $ARGV[0])
  35. {
  36. die "Error opening $ARGV[0]\n";
  37. }
  38. $INname = $ARGV[0];
  39. $ARGV[0] =~ /(.+)\../;
  40. $OUTname = $1.'.tra';
  41. if (defined $ARGV[1])
  42. {
  43. $OUTname = $ARGV[1]
  44. }
  45. open IN, "<$INname" ||
  46. die "Error opening $INname:$!\n";
  47. binmode IN;
  48. open OUT, ">$OUTname" ||
  49. die "Error opening $OUTname:$!\n";
  50. binmode OUT;
  51. print OUT $TRAHeader;
  52. print OUT pack('L',$curver);
  53. print OUT pack('C',$OBJID{'ambient'});
  54. saveRGB(%AMB);
  55. read IN, $C, 2;
  56. $CHUNK_MAIN = unpack "S", $C;
  57. ($CHUNK_MAIN == 0x4d4d) || die "Not a 3ds file\n";
  58. read IN, $C, 4;
  59. $GLEN = unpack "L", $C;
  60. printf "0x%x\n",$GLEN;
  61. while (!eof(IN) && ($POS < $GLEN))
  62. {
  63. (read(IN,$C,2)==2) || die "Unexpected EOF reading chunk\n";
  64. $CHUNK = unpack "S", $C;
  65. (read(IN,$C,4)==4) || die "Unexpected EOF reading chunk lenght\n";
  66. $CLEN = unpack "L", $C;
  67. die "Chunk size error" if $CLEN == 0;
  68. if ($procs{$CHUNK})
  69. {
  70. $POS += $procs{$CHUNK}->()+6;
  71. }
  72. else
  73. {
  74. $POS += $CLEN;
  75. }
  76. seek IN, $POS, SEEK_SET;
  77. }
  78. foreach $face (@faces)
  79. {
  80. print OUT pack("C",$OBJID{'tri'},1);
  81. saveVec($vertex[$face->{'v1'}]);
  82. saveVec($vertex[$face->{'v2'}]);
  83. saveVec($vertex[$face->{'v3'}]);
  84. saveRGB(%COLOR);
  85. saveSurf(%SURFACE);
  86. }
  87. @faces = ();
  88. @vertex = ();
  89. sub saveVec {
  90. my ($vec) = @_;
  91. print OUT pack("d3",$$vec{'X'},$$vec{'Y'},$$vec{'Z'});
  92. };
  93. sub saveRGB {
  94. my (%vec) = @_;
  95. print OUT pack("d3",$vec{'R'},$vec{'G'},$vec{'B'});
  96. };
  97. sub saveSurf {
  98. my (%vec) = @_;
  99. print OUT pack("d3",$vec{'Kd'},$vec{'Ks'},$vec{'Ns'});
  100. };
  101. sub saveDouble {
  102. my ($val) = @_;
  103. print OUT pack("d",$val);
  104. };
  105. sub EDIT3DS {
  106. print "Loading Edit\n";
  107. return 0;
  108. }
  109. sub EDIT_OBJECT {
  110. $ObjName = "";
  111. {
  112. read (IN, $C, 1);
  113. last if $C eq "\0";
  114. $ObjName .= $C;
  115. redo;
  116. }
  117. print "Loaded $ObjName\n";
  118. return length($ObjName)+1;
  119. }
  120. sub OBJ_TRIMESH {
  121. print "Loading Trimesh ($ObjName)\n";
  122. foreach $face (@faces)
  123. {
  124. print "writing !\n";
  125. print OUT pack("C",$OBJID{'tri'},1);
  126. saveVec($vertex[$face->{'v1'}]);
  127. saveVec($vertex[$face->{'v2'}]);
  128. saveVec($vertex[$face->{'v3'}]);
  129. saveRGB($COLOR);
  130. saveSurf($SURFACE);
  131. }
  132. @faces = ();
  133. @vertex = ();
  134. return 0;
  135. }
  136. sub TRI_VERTEXL {
  137. my ($count,$i);
  138. read IN,$C,2;
  139. $count = unpack "S", $C;
  140. print "Loading $count vertexes\n";
  141. for ($i=0;$i<$count;$i++)
  142. {
  143. read IN, $C ,4;
  144. $vertex[$i]->{'X'} = unpack "f", $C;
  145. read IN, $C ,4;
  146. $vertex[$i]->{'Z'} = unpack "f", $C;
  147. read IN, $C,4;
  148. $vertex[$i]->{'Y'} = unpack "f", $C;
  149. }
  150. return $count*12+2;
  151. }
  152. sub TRI_FACEL {
  153. my ($count,$i,$tmp);
  154. read IN,$C,2;
  155. $count = unpack "S", $C;
  156. print "Loading $count faces\n";
  157. for ($i=0;$i<$count;$i++)
  158. {
  159. read IN, $C ,2;
  160. $faces[$i]->{'v1'} = unpack "S",$C;
  161. read IN, $C ,2;
  162. $faces[$i]->{'v2'} = unpack "S",$C;
  163. read IN, $C ,2;
  164. $faces[$i]->{'v3'} = unpack "S",$C;
  165. read IN,$tmp,2
  166. }
  167. return $count*8+2;
  168. }
  169. sub OBJ_CAMERA {
  170. my (%org,%targ,$roll,$fov,$xtoy);
  171. $xtoy = 1;
  172. print "Loading Camera ($ObjName)\n";
  173. read IN, $C ,4;
  174. $org{'X'} = unpack "f", $C;
  175. read IN, $C ,4;
  176. $org{'Z'} = unpack "f", $C;
  177. read IN, $C,4;
  178. $org{'Y'} = unpack "f", $C;
  179. print "Origin - $org{'X'}:$org{'Y'}:$org{'Z'}\n";
  180. read IN, $C ,4;
  181. $targ{'X'} = unpack "f", $C;
  182. read IN, $C ,4;
  183. $targ{'Z'} = unpack "f", $C;
  184. read IN, $C,4;
  185. $targ{'Y'} = unpack "f", $C;
  186. print "Target - $targ{'X'}:$targ{'Y'}:$targ{'Z'}\n";
  187. read IN, $C ,4;
  188. $roll = unpack "f", $C;
  189. read IN, $C ,4;
  190. $fov = unpack "f", $C;
  191. print "Roll,Fov - $roll,$fov\n";
  192. #----------------------------------
  193. print OUT pack "C", $OBJID{'camera'};
  194. saveVec(\%org);
  195. saveVec(\%targ);
  196. saveDouble($roll);
  197. saveDouble($fov);
  198. saveDouble($xtoy);
  199. return 32;
  200. }