HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

RDZ's Guide to Finalising an MDL (From Milkshape with kdub's Exporter)

04-25-2005, 06:19 PM#1
Rao Dao Zao
I've researched all of this myself, and I'm interested to see what all the real MDL gurus think of it. If anybody's got anything interesting to add, please do.
_________________________________________________
GETTING YOUR MILKSHAPE EXPORTED MDL INTO WARCRAFT
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
(Using kdub's exporter)

--------------------
Finalising the MDL:
--------------------

Before doing anything: Find and replace #IND with 0
Now, construct your header - from a Sequences, Textures and Materials section.
_ _ _________ _ _
- - SEQUENCES - -
¯ ¯ ¯¯¯¯¯¯¯¯¯ ¯ ¯

Sequences 1 {
Anim "Stand" {
Interval { 42, 2083 },
Rarity 5,
NonLooping,
MinimumExtent { -200, -200, -200 },
MaximumExtent { 200, 200, 200 },
BoundsRadius 100,
}
}

NEW ANIMATIONS: Divide keyframe in Milkshape by 24, then multiply by 1000. Round to nearest 1.
THE SEQUENCES MUST COME IN THE ORDER THAT THEY COME IN MILKSHAPE - I.E. Animation from 1 - 25 above animation from 60 - 70 etc

Explanation:
The interval is the period in which the specific animation occurs, start frame followed by end frame. MAKE SURE SEQUENCES DO NOT OVERLAP, OR START ON THE SAME FRAME THAT THE LAST ONE ENDED ON.

Rarity is used for variations of different animations, for example if you have three stand animations and one is longer and thus should not happen so often, increase its Rarity value. This line is entirely optional.

NonLooping means that the animation will not repeat itself - it is crucial for morph, death and attack animations, maybe more. If it does not exist in these animations, the model will constantly cycle, say, the death animation until the unit is removed, even though it is dead and should be decaying.

Maximum/Minumum Extent - I actually have no idea what these are used for, but hey.

BoundsRadius is how far your model extends from the origin... It is used to define whether the model is displayed or not at the edge of the screen - for example, if there was no BoundsRadius line, as soon as the origin in off the screen, the whole model disappears, even if its head should still be visible. Also affects selection - the model can be clicked on within its BoundsRadius to select it, but clicking model parts outside will not select it. Again, if there is no BoundsRadius line the model will be unselectable, except by drag selecting.
_ _ ______________________ _ _
- - MATERIALS AND TEXTURES - -
¯ ¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯ ¯
NOTE: The following material does not do team-colour: it is a simple way of getting everything working.

Textures 1 {
Bitmap {
Image "Textures\RDZMech.blp",
}
}
Materials 1 {
Material {
Layer {
FilterMode None,
static TextureID 0,
}
}
}

Header with two textures and teamcolour on the main one:

Textures 3 {
Bitmap {
Image "",
ReplaceableId 1,
}
Bitmap {
Image "Textures\XanSkin.blp",
}
Bitmap {
Image "Textures\RDZGlow.blp",
}
}
Materials 2 {
Material {
Layer {
FilterMode None,
Unshaded,
static TextureID 0,
}
Layer {
FilterMode Blend,
TwoSided,
static TextureID 1,
}
}
Material {
Layer {
FilterMode Additive,
Unshaded,
TwoSided,
static TextureID 2,
}
}

}

Explanation:
The first texture is "ReplaceableId 1," which creates teamcolour depending on the owner.
The second is the model's main skin, which may have an alpha channel which will define where teamcolour shows through.
The third is a glow for some fire, which is actually a soft sphere on black. The "FilterMode Additive" makes this not show a black square with glow in the middle, but the transparent glow itself.
Unshaded makes the geosets with this material unaffected by lighting; they will always display clear and witout shadows. TwoSided - self explanatory, the skin displays on both sides of the geoset, useful for single-plane weapons etc.
_ _ ________________ _ _
- - Portrait Cameras - -
¯ ¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯ ¯
Portrait camera: modify position and target for size of model.
(Positions: { X, Y, Z }, Z being height)

Camera "Camera01" {
Position { 100, 100, 75 },
FieldOfView 0.785398,
FarClip 1000,
NearClip 8,
Target {
Position { 0, 0, 50 },
}
}

It's a bit of a guessing game finding the best coordinates for your camera, but it's just a matter of tweaking to get the right values.

--------------------
Nice Touches:
--------------------

Now that the model is functional, use these nice tips and tricks to add special effects and finishing touches to your Milkshape model...
____________
GEOSET ANIMS
¯¯¯¯¯¯¯¯¯¯¯¯
Making Geosets disappear in animations:

GeosetAnim {
Alpha 2 {
DontInterp,
6250: 1,
6458: 0,
}
GeosetId 0,
}

0 = invisible, 1 = visible. In between values can be used.
Change "DontInterp" to "Linear" for smooth fade.
AT THE EXACT START FRAME OF EACH SEQUENCE INVOLVED, THE ALPHA MUST BE DEFINED!
If the geosets do odd disappearing acts, make sure that, for example, if it is a fade-out in a death animation that begins at 1530, there is a line in the geosetanim like "1530: 1" or whatever.

NOTE: Different FilterModes on your materials affect the working of linear GeosetAnims - Additive, Blend work fine, but a teamcolour material will not fade out the model, but fade it into teamcolour. Transparent doesn't work, the model just flashes fitfully occasionally in my experience. I have reason to believe that DontInterp animations work fine with all FilterModes. So be careful.
_____________
EVENT OBJECTS
¯¯¯¯¯¯¯¯¯¯¯¯¯
Make "splats", spawn models and sounds play at certain points in the animation:

EventObject "SPNxDNBL" {
ObjectId 14,
EventTrack 1 {
6250,
}
}

Append these to the end of your MDL and ***add a line to the end PivotPoints list defining the position***, copy off a bone if you're stuck.

War3ObjectData.doc can be found somewhere on the wc3campaigns MDL forums, which details what codes to use to get which effects/sounds...

A NOTE ON PIVOTPOINTS: These are points (well, duh) around the model. Each object in the MDL directly relates to a PivotPoint - ObjectID 0, probably your root bone, will be at the position of the first PivotPoint. ObjectID 1 wil be at the position of the second PivotPoint and so on.
_________________
ATTACHMENT POINTS
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Attachment "Origin Ref " {
ObjectId 47,
}

Make sure this has a corresponding PivotPoint. It can have a "Parent X," line added, to make it follow a bone or something.
Another little trick with the attachment is using it to build in another model - like you would do with spell/item art, but actually hard-wired into the model:

Attachment "Chest Ref" {
ObjectId 15,
Parent 5, // "Mesh07
Path "FlyingSheep2.MDL",
Visibility 5 {
DontInterp,
667: 1,
9833: 0,
13333: 0,
73000: 0,
80000: 0,
}
}

This attachment will add on "FlyingSheep2.mdX" to the model's chest region. FlyingSheep2 itself is actually just the wings with a single stand animation, that of them flapping, and I was using this to test out a method of attaching flapping wings to models without geomerging inanimate ones. Also note the "Visibility" section - this can be used to define if attachments display or not during animations, operating exactly like a GeosetAnim. Good for making your extra bits disappear in the death and decay anims. Not sure if the Attachment model's animations operate in synch with the model; I don't think they would play a death animation when the real model dies etc.
If you make sure that your attachment model only has one animation, you can keep the file-size very low, even if it's been made from an entire unit.
___________________
SCREWING WITH BONES
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Fire and/or hero glow:
Create a plane facing forward, square for best results, and make sure each plane has its own bone in the centre, which has no children - if a row is needed for a sword's hero glow, for example, have each bone to be Billboarded the child of a single bone, not children of each other. Or just create the bones whatever way and change the "Parent X," line to the ID of whatever bone you want the "glow" to follow.
Add the line:
Billboarded,
To the bone. This will make it always face the camera (unless you created the plane facing the wrong direction, in which case the side or something will always face the camera).

Scaling:
Similar to the Rotation and Translation sections that will already exist for each bone, scaling allows the size of geometry attached to the bone to be changed.
Scaling 3 {
Linear,
12083: { 1, 1, 1 },
12916: { 2.05, 2.05, 2.05 },
13750: { 1, 1, 1 },
}
Add this to the bone, and change what keyframes each size is applied in. Scales in { X, Y, Z }. 1 = normal size, 2 = double, 0.5 = half etc. This will cause a smooth translation between scales over the period between keyframes. I have reason to believe that changing "Linear" to "DontInterp" (opposite of what we did with geosetanims) will create an instant change rather than smooth scaling. If problems arise, try setting the scale at the first frame of the sequence, as with the geosetanims. Also remember that scaling is inherited like rotation and translation - if you scale the root bone to 10 and the pelvis to 10, then the pelvis will actually be 100 times the size, or something like that. If it's causing problems, just change the "Parent X," line to another objectID.

____________
TVERTEXANIMS
¯¯¯¯¯¯¯¯¯¯¯¯
Yup, I've (finally) worked out roughly what to do with these.
First of all, you need to add in a section like this, just below the normal Sequences section:

GlobalSequences 1 {
Duration 2833,
}

That's all it does; define the duration of your TVertexAnim. Then you need to add in the TVertexAnim iteself, below the Materials section.

TextureAnims 1 {
TVertexAnim {
Translation 2 {
Linear,
GlobalSeqId 0,
0: { 0, 0, 0 },
2833: { 0, 1, 0 },
}
}
}

This will simply cause the texture to move 'forward' (I've not worked out directions yet) once over 2833, bringing the image back to its 'start'. The distance, I believe, is relative to the image size; 1 makes it move the length of itself, 1.5 would make it go faster by moving the image one and a half times its length etc.
Finally, you must add a reference to this in the Material that will use it:
TVertexAnimId 0,
The Id is counted in the same manner as everywhere else.
You will also need to add these lines to the Texture that is being animated:
WrapWidth,
WrapHeight,
This will make the texture pan nicely, whereas a texture lacking these 'stretches' the edges until the mesh shows a set of lines of the edge line of pixels, until it starts the animation again.
04-26-2005, 02:35 PM#2
Guest
Quote:
Originally Posted by Robe
Maximum/Minumum Extent - I actually have no idea what these are used for, but hey.

BoundsRadius is how far your model extends from the origin... It is used to define whether the model is displayed or not at the edge of the screen - for example, if there was no BoundsRadius line, as soon as the origin in off the screen, the whole model disappears, even if its head should still be visible. Also affects selection - the model can be clicked on within its BoundsRadius to select it, but clicking model parts outside will not select it. Again, if there is no BoundsRadius line the model will be unselectable, except by drag selecting.

I made some experiments with the maximum/minimum extent values and they seems to control the visibility range of the model (the BoundsRadius has no part in it) This make sense because you have 3 axes (x,y,z) divided in positive and negative by the origin point: 6 values in total. Also i've found that you must enter those lines either at the start of the mdl, and at the end of each geoset.
04-26-2005, 07:37 PM#3
Rao Dao Zao
At the end of each geoset, eh? Why is that? I mean, you tell the MDL at every animation, which I can understand, and at the top, which is fine. But why at each geoset?
04-26-2005, 09:12 PM#4
Guest
Maybe each geoset can have a different visibility range? Well, i'm not SURE if they both are needed: but all the mdl files that i checked have this composition. That was all i need to know, so i didn't test more.
Oh, btw, thanks for the info about the BoundRadius
04-28-2005, 05:41 PM#5
Rao Dao Zao
My pleasure. It is my hope that everybody can benefit from my research...