Results 1 to 28 of 28

Thread: Milkshape ms3d importer/exporter for 3ds Max and Gmax

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Member Member KnightErrant's Avatar
    Join Date
    Jan 2007
    Location
    Huntsville, Alabama USA
    Posts
    458

    Default Milkshape ms3d importer/exporter for 3ds Max and Gmax

    In between tearing our hair out over animation problems with offset horse
    meshes, Bwian and I have been working on an importer/exporter of
    Milkshape .ms3d files into 3ds Max and Gmax. All the OBVIOUS bugs seem
    to be gone now so consider this an alpha release. You can find the script
    and some other files here:

    http://www.twcenter.net/forums/downl...o=file&id=1718

    The zip file contains the MaxScript ms3dimportexport_ver1_0.ms,
    a readme.txt file, and two files needed by Gmax users but not by
    3ds Max users. The script can be placed in your scripts subdirectory
    or any place convenient to your workflow. Click the Max Script menu item,
    then Run Script, then mouse to the directory containing
    ms3dimportexport.ms and double click to run it. It will display a simple
    rollout with import and export buttons.

    Importing will bring in all the mesh data, bones, bone assignments and
    vertex weighting, along with the bounding sphere and group names,
    types, and flags needed to reconstruct a mesh file. Details are covered
    in the Technical bits below.

    Animations can be done with the Python animation utility animmerge and
    then imported the same way as a regular model. After modification,
    the animated model can be exported and the new animations extracted
    to a cas file with the animextract utility.

    Regular units, mounts, and siege engines are supported as are their
    animated versions except for siege engines (the animation utilities
    don't support animating siege engines).

    Please report any bugs you find here or send a PM. I don't have a copy
    of 3ds Max so if problems come up in the part of the code that writes
    the binary .ms3d file, we'll have to work together on that.
    (Gmax can't write files.)


    Acknowledgements:

    Bwian for getting me started with Gmax and sending a link to Vercingetorix's script.

    Vercingetorix for writing the wonderful script in the first place.

    Aymar de Bois Mauri for explaining that "groups" in 3ds Max can only be made by making multiple meshes,
    a conceptual roadblock for me coming from Milkshape.

    GrumpyOldMan for sending along the listener data grabbing utility: GmaxSLGRAB.exe (discussed below).


    Technical Bits for Gmax Users:
    ------------------------------

    Spoiler Alert, click show to read: 
    (1) The export procedure for Gmax:

    Among the many runtime features turned off in Gmax, the ability to write
    ASCII or binary files is one of the most frustrating things to lose. The
    procedure I've seen other authors do for Gmax is export to the listener
    window and then cut and paste into a text file. Fortunately,
    GrumpyOldMan heard my pain and found a utility that does this for you.
    This has been included in the zip file and is called GMaxSLGRAB.exe. Once
    you have exported to the listener double click this file. It displays a small
    Window with one big button with "grab" as the label. Click the
    "grab" button and it copies the data from the listener and prompts
    you for a filename to save it to. Note that it supplies an .xml filter but
    my recommendation is to explicitely type a .txt extension for your filename
    to override this. It will warn you if you are going to overwrite an existing
    file and it displays "done" after writing the file.

    Now your data is out but in a useless made up format of mine. Now you
    run the supplied Python utility ascii2ms3dconverter.py by either double
    clicking it or right clicking and selecting open. It pops up a filechooser
    and you select the text file you just made and it reads the data and
    converts it to binary .ms3d format. Only slightly more complicated
    than the 3ds Max way.

    (2) Exporting big models clobbers the listener window, here's a workaround:

    Cut and paste the following into a file and name it clearlistener.mcr.

    macroScript clearListener
    category:"Helpers and Gizmos"
    internalcategory:"Helpers and Gizmos"
    tooltip:"Clear Listener"
    ButtonText:"Clear Listener"
    Icon:#("Helpers",1)
    (
    on execute do clearlistener()
    )


    Place it in your ui\macroscripts directory. In Gmax click the customize menu
    item and then select customize user interface. In the dialog that pops up
    click the toolbars tab and scroll down until you see clearlistener, click and
    drag it to your main toolbar. Then click the save button to update your
    configuration. Now when the listener gets filled up by an export and won't
    allow you to type in it, you can hit this button to clear it.



    Technical Bits for All Users:
    -----------------------------

    Spoiler Alert, click show to read: 
    (1) Where's the data stored?

    In Milkshape the group name, type, and flag are stored in the group
    comments and the bounding sphere data is stored in the model comment.
    In 3ds Max and Gmax the name of a given mesh is the group name and
    the group type and flag are stored in user defined properties. To see them
    select the mesh with the Select Objects dialog, then under the edit menu
    item select Object Properties, then select the User Defined tab to see
    the group name and flag. The bounding sphere is stored in the root bone:
    bone_pelvis for humanoids, bone_H_Saddle for horses, bone_camel_root
    for camels, bone_E_platform for elephants, and USUALLY bone_body for
    siege engines. The bounding sphere is stored as ASCII floats joined by
    % signs. (Oddity of Gmax, maybe of 3ds Max, you can store strings with
    spaces in User Properties and see them there, but only the first whole
    word comes back out, hence the need to make strings with no spaces.)

    When dealing with animated files, the .cas header, hierarchy, and footer
    strings are stored in the first three joint comments in Milkshape.
    In 3ds Max and Gmax they are stored in the root bone as well and you
    can see them in User Properties. They also are ASCII format numbers
    joined by percent signs. Underscores would have looked better but
    texture paths for siege engines have underscores so I couldn't use
    them because I tokenize the string based on the chosen delimeter.
    Naturally for siege engines, the three texture paths are stored here,
    it's just that their keywords are: animheader, animhierarchy, and
    animfooter. This may change if I get animation utilities to work with
    siege engines.


    (2) Known Deficiencies:

    The script works on unanimated regular units converted by GrumpyOldMan's
    converter and unanimated mounts and siege engines converted by my
    Python converter. It also works for animated regular units and mounts.
    It WON'T work for animated siege engines because I store the three
    texture paths for siege engines in the joints comments but I also
    store the .cas file animation headers, hierarchy, and footers in the joints comments. Haven't worked through this conflict yet.

    Not a deficiency of this script but if people are going to start using the
    Python animation utilities (version 1_1 uploaded June 18, 2007) there are
    three known bugs.
    1 - on line 1092 in the animextract function there's this extraneous entry
    float_vec3.fromfile( fidcas, 7 )
    I can't fathom how it got there, it wasn't there when I tested everything.
    Just comment it out with a pound sign like
    # float_vec3.fromfile( fidcas, 7 )

    2 - Converttxttocas doesn't convert the degrees back to radians. Oops,
    it's fixed just have to post an updated copy.

    3 - I didn't check for uppercase extensions so some cas files that look like
    name.CAS
    don't get exported to. Bwian found this one in the exportskeleton function. Also fixed just not released.


    (3) Modifier Stack:

    The export only works if the skin is at the top of the modifier stack for
    each mesh in the model. You can do this manually by clicking and holding
    the modifier and moving it. A "feature" of Gmax at least is that if you do
    this to the skin modifier to move it to the top of the stack it loses all
    its information about bone assignments and weighting. On the other hand,
    if you manually move all other modifiers below the skin modifier, the
    information is retained and the export works. I've duplicated this procedure
    in the script so that if the skin modifier is NOT at the top of the stack,
    I make full copies of all the modifiers above the skin modifier, delete
    the originals so that the skin modifier is at the top, and then recreate
    the other modifiers, in order, below the skin modifier. The script will
    stop and ask if you want it to do this procedure or to terminate.


    (4) Trying to reconstruct the basepose on exporting an animated model:

    Having used Milkshape first I expected animated files to look the same way
    in Gmax, that is, be in the basepose and only change to animations when
    you hit the animate button. Bwian explained this isn't the way it works,
    animations are just done differently between the two. If I simply exported
    the same way I did a regular model I get the vertex positions of whatever
    frame happens to be displayed at the time. If you opened this is Milkshape
    you'd see the bones in the basepose and a distorted mesh. The animations
    are perfectly good and you can run animextract to make a perfectly good
    .cas file but this is still unsightly.

    So to get an approximation to the basepose mesh I followed this procedure.
    For each vertex get its primary bone assignment. In that bone's coordinate
    system get the vertex position, i.e., relative to the pivot point. Now get
    the relative bone positions all the way up the hierarchy to the root bone
    and add them up. This SHOULD be the vertex position in world or object
    or whatever the outside coordinate system is. (bone_pelvis is hard coded
    to be at (0, 0, 0) since its position got overridden by the animation data.)
    For armored_sergeants this was good to about a percent, too large to be
    round-off error but too small to detect in Milkshape. So the warning is:
    don't reimport a previously exported animated model, it's akin to making
    a xerox of a xerox. Again, this is just for aesthetics, you only want the
    animation data from an exported animated model, you never backconvert
    these to meshes.


    (5) Bone Assignments:

    Mesh files always have two bone assignments, a primary and a secondary,
    even if the vertex weighting on the secondary is zero. Gmax ignores an
    assignment with a zero weight so to preserve these two bones I weight
    the secondary one with 0.00001 and the primary with 0.99999. This
    satisfies Gmax to keep two assignments but on conversion back to
    Milkshape format it rounds back to 100 percent on the primary and
    0 percent on the secondary and everybody's happy. Custom made models
    in Milkshape frequently have only a single bone assignment so the
    secondary Id is -1. To be safe and ensure that there are always two
    bone assignments I arbitrarily made the secondary assignment to the
    root bone with a weight of 0.00001.

  2. #2

    Default Re: Milkshape ms3d importer/exporter for 3ds Max and Gmax

    During testing, we also ran this thing with custom skeletons, and it worked with those too. IT was possible to get animations and meshes through from MS3D to Max using hte SMD file format...but you got a messy end result with no comments, groups or other useful stuff. I also had a few issues with animations and meshes afterwards.

    This script was able to move the models intact, with all the uspporting data still present, the groups as seperate objects, and all the stuff needed to rebuild a solid model once you get back to MS3D. VERY important!
    Careless Orc Costs Lives!

  3. #3
    CeltiberoRamiroI Member Monkwarrior's Avatar
    Join Date
    Apr 2004
    Location
    Salduie/Caesaraugusta/ Sarakusta/Saragossa
    Posts
    828

    Default Re: Milkshape ms3d importer/exporter for 3ds Max and Gmax

    Each time I try to export a model as ms3d I get this error message:



    In this case I had a single shield on the skeleton (I'm starting some kind of library) and I wanted to attach on this model a part from a RTW model (the central part of the shield, I don't know the name in English). Once attached, I try to export it as ms3d with this result.

    I get the same message in a direct conversion:
    - Firstly ms3d to max (no problem)
    - Secondly, the same max (with no modification) to ms3d (error message).

    Am I doing anything wrong?

  4. #4
    Member Member KnightErrant's Avatar
    Join Date
    Jan 2007
    Location
    Huntsville, Alabama USA
    Posts
    458

    Default Re: Milkshape ms3d importer/exporter for 3ds Max and Gmax

    @Monkwarrior,

    I don't think you're doing anything wrong, just found a
    failure mode in the script. From where it failed it looks like
    it didn't form the bonename_array and now its trying to find
    the root bone with an undefined name. Is the last line in the
    listener something like:
    "number of bones in the model: 0"

    Anyway, I'll PM you an e-mail, easiest thing is to attach the
    original .ms3d file and I'll duplicate the error. Then I can turn
    on some debugging information to see what's going on.

  5. #5
    Warhammer: Total War Team Member Alletun's Avatar
    Join Date
    Mar 2007
    Posts
    121

    Default Re: Milkshape ms3d importer/exporter for 3ds Max and Gmax

    Wow this is great! gonna test it out immediately

  6. #6
    Warhammer: Total War Team Member Alletun's Avatar
    Join Date
    Mar 2007
    Posts
    121

    Default Re: Milkshape ms3d importer/exporter for 3ds Max and Gmax

    ok this is what i got so far:

    1) tried importing an unedited dismounted latinkon. worked like a charm :)

    2) tried importing the custom model / skeleton of a stone troll for warhammer:tw. got this error:


    All joinst were zero-jointed etc.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Single Sign On provided by vBSSO