Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I found a script for converting m3 files (3D models used in Starcraft 2) to obj files, but I do not know how to use it. All the information I got was "Well, here is the script.", so I cannot really give you much information, besides the fact that I have never heard of PHP before.

Here is the script

<?php
#########################
# $argv[1] can be edited to any custom path
#########################
  $temp = explode(".m3", $argv[1]);
    $file = $argv[1];
    $path = $temp[0];# "./Assets/Doodads/AiurTree/AiurTree_06";
    echo("Exporting Model $path to $path.obj\n\n");
    $file = fopen($file, 'rb') or die("Failed to open $file!\n");
    if(fread($file,4) != "33DM") die("Failed! File is not a StarCraft 2 model!\n");
    fseek($file, 4); # find where tags start
    $index = unpack(V, fread($file, 4));
    # search for __8U "5F 5F 38 55" tag for vertex offset
    $offset = $index[1];
    while(1){
        fseek($file, $offset+16);
        $string = fread($file, 4);
        if ($string == '__8U'){
            $offset+=20;
            break;
        }
        $offset++;
    }
    fseek($file, $offset);
    $index = unpack(V, fread($file, 4));

    fseek($file, $offset+4);
    $maxVerts = unpack(V, fread($file, 4)); # maximum extents
    $maxVerts[1] = $maxVerts[1] + $index[1];
    fseek($file, $offset+6);
    $version = unpack(V, fread($file, 4)); # up to 7 versions currently known
    if ($version[1] == 7 or $version[1] == 0){
      $EOB = 4; # versions have different number of values after uv - value to reach end of block
    } elseif ($version[1] == 1 or $version[1] == 2 or $version[1] == 3 or $version[1] == 6){
      $EOB = 8;
    } else {
      $EOB = 8;
      echo("Model not yet supported, report it to Teal\n");
      //die("Model not yet supported, report it to Teal");
    }
    echo("Model type $version[1]\n");
    if ($version[1] == 2) echo("This model will have invalid UV coordinates... working on it.\n");
    fseek($file, $offset+32); # face data
    $indexFaces = unpack(V, fread($file, 4));
    fseek($file, $offset+36);
    $maxFaces = unpack(V, fread($file, 4));
    $maxFaces[1] = $maxFaces[1]*2 + $indexFaces[1];

    $i = 0;
    $k = 0;
    $offset = $index[1];
    while(1){
      if ($offset >= $maxVerts[1]) break;
      for($j=0;$j<3;$j++){ # read verts
        fseek($file, $offset);
        $temp = unpack(f, fread($file, 4));
        $vert[$i] = $temp[1];
        $offset +=4;
        $i++;
      }
      $offset+=12;
      for($j=0;$j<2;$j++){ # read UV
        fseek($file, $offset);
        $temp = unpack(v, fread($file, 2));
        if ($temp[1] > 2046){
          $uv[$k] = $temp[1] / 65536;
        } else {
          $uv[$k] = $temp[1] / 2046;
        } 
        $offset +=2;
        $k++;
      }
      $offset+=$EOB;
    }
    $i=0;
    $offset = $indexFaces[1];
    while(1){ # read faces
      if ($offset >= $maxFaces[1]) break;
      fseek($file, $offset);
      $temp = unpack(v, fread($file, 2));
      $face[$i]=$temp[1];
      $i++;
      $offset+=2;
    }
    $out = fopen($path . ".obj", 'w+');
    for($i=0; $i<sizeof($vert); $i+=3){
      fwrite($out, "v " . $vert[$i] . " " . $vert[$i+1] . " " . $vert[$i+2] . "\n");
    }
    for($i=0; $i<sizeof($uv); $i+=2){
      fwrite($out, "vt " . $uv[$i] . " " . (1-$uv[$i+1]) . "\n");
    }
    for($i=0; $i<sizeof($face); $i+=3){
      fwrite($out, "f " . ($face[$i]+1) . "/" . ($face[$i]+1) . " " . ($face[$i+1]+1) . "/" . ($face[$i+1]+1) . " " . ($face[$i+2]+1) . "/" . ($face[$i+2]+1) . "\n");
    }
    fclose($out);
    echo("Done!\n\n");
?>

How can I use this?

share|improve this question

1 Answer 1

up vote 7 down vote accepted

You need to save the script as a file named script.php(or anything with .php). Copy everything, paste it into a text editor of your choice. Place it somewhere, probably best in /Users/your-username/script.php, or any other folder you like.

Now you can run the script using the php binary which comes with OS X.

Open the Terminal.app from Applications → Utilities. Enter the following line

php ~/script.php ~/file.m3

to execute the script. ~ is short for your home directory. Of course, file.m3 needs to exist in your home directory as well and be the StarCraft file you want to convert.

The resulting .obj file will probably be placed in the same folder as the m3 file.

share|improve this answer
    
Thanks. I will try that in a minute. –  Justin Jul 5 '11 at 20:27
    
Some notes: You don't need to name it php, it's just easier to spot that way. Also, the author of the script didn't really care to include a usage message, which would help you to understand the script. It runs on my Mac, but I can't test with a real file ;) –  slhck Jul 5 '11 at 20:29
    
Works perfectly. The only problem is in the script itself, but, by examining the syntax, I think I have found a way to fix that. Thanks a lot! –  Justin Jul 6 '11 at 22:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.