Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


Neverwinter Nights: Enhanced Edition has been released! Visit to make an order. NWN:EE FAQ is available.
Soundtracks for BG:EE, SoD, BG2:EE, IWD:EE, PST:EE are now available in the Beamdog store.
Attention, new and old users! Please read the new rules of conduct for the forums, and we hope you enjoy your stay!

How to manually create animmeshes - a tutorial

LaputianBirdLaputianBird Member Posts: 103
I made a tutorial for a friend some time ago, regarding how to create an advanced animmesh with manual vert deformation/transformation, unlike the parametric approach used in nwmax. Once EE will provide a complete range of shaders, animmeshes are going to become obsolete for the most part, but there might be some cases where they are still the better option, or however an alternative way to achieve the same result, using a 3d modeling program innstead of having to write some code in the shader scripting language.

The technique uses a mix of 3dsmax modeling and of ASCII manipulation, and I'm going to split it up in a few separate posts.

First of all, what is an animmesh? It can be considered as a primitive analogue of the skinmesh. The main difference is that skinmeshes verts are animated in real time by the engine, through their bones. Animmeshes use verts deformation/transformation as well, but everything is pre-calculated and "baked in" from the start, with no help from the game engine.

As a result, animmeshes have a few relevant disadvantages over skinmeshes:
- the file size can grow significantly depending on the length of your animation and the number of verts of your geometry
- while it is possible to easily add as many animations as desired to a skinmesh once the initial setup is complete, animmeshes would require repeating the whole setup process for every new animation, as all verts deforms/transforms always need to be pre-calculated
- animmeshes don't use animation keys for their pre-baked verts transforms, they use a sampleperiod instead. This means that it isn't possible to speed up or down the animation arbitrarily. It is still possible to add a separate set of animations keys that apply to the whole mesh and can be combined with the per-vert animations (I'll include an example)

But they also have advantages:
- animmeshes don't suffer from "max number of bones" limitations (as they don't use any!)
- while skinmeshes are limited to verts animations, the texture verts (tverts) of an animmesh can also be animated (it can be used to create a waterfall or a moving ocean foam, for instance)
- it is possible to animate specific verts or groups of verts directly, in ways that would require the use of a high number of bones with a skinmesh (which the engine wouldn't allow)

In short: animmeshes allow for a high degree of freedom, at the cost of having to pre-calculate all animation data.

A closer look at the ASCII format of animmeshes (to clarify, it's aniM-Mesh, with 2 m's, or the engine won't recognize the mesh type).

An animmesh is defined in the geometry section of a nwn model just like a trimesh.

In the specific animation section (to note, the animation length), the animmesh is given a sample period,

and a set of animverts

There is no explicit declaration of the number of the animation frames. It can be calculated with this formula: (animation length)/(sample period). Since the result has to be an integer (a whole number), it means that the animation length must be a multiple of the sample period. Example, if we set the sample period to 0.4, the animation length must be one of the series 0.8, 1.2, 1.6, 2.0, 2.4 etc etc. In other words, it is better practice to define the sample period and the number of animation frames first, and calculate the resulting animation length as the last step, with the formula (number of frames)*(sample period) .

There is the explicit declaration of the number of animated verts (animverts). The formula is (number of mesh verts)x(number of frames + 1). In our example, (258)x(4+1)=1290.
At each and every frame, the engine needs the position data of each and every vertex of the animmesh, and needs one additional set of vertex positions to close the loop of the animation.

There is no visible difference between the animverts that belong to a frame and those that belong to the previous or next frame. The engine assigns an animvert to one frame or the other based on its position in the list. In our example, of those 1290 animverts, the first 258 belong to the first frame, the second 258 to the second frame etc. That means, animmeshes are extremely fragile under this regard, one single mistake in the text/ASCII manipulation (a missing vertex after a copy and paste for example) can completely break the animation.

If you are curious as to what an apple mesh is doing in a bard song vfx...

[ actual tutorial coming in next post ]



  • NWN_TömlNWN_Töml Member Posts: 88
    edited February 2018
    Thank you very much. Animeshs are great even they are way to huge (mdl filesize wise) atm. But they definately make some cool effects. World of warcraft designers use them alot. An example is the way they do the "bubbling cauldrons"... ;)

    Oh an btw. I always set the "sample period" to very low. So you save some mdl size ;)

  • LaputianBirdLaputianBird Member Posts: 103
    NWN_Töml said:

    Oh an btw. I always set the "sample period" to very low. So you save some mdl size ;)

    Actually it's not the sample period what makes the file bigger, it's the number of frames, which is given by (animation length)/(sample period). The engine requires a whole set of vert positions (optionally of tvert positions too) at the end of every sample period (i.e for every frame)

  • LaputianBirdLaputianBird Member Posts: 103
    So, coming to the technique, and starting with 3dsmax/other 3d modeling program.

    Part 1:

    1. Create a basemodel, whether a placeables, an effect, or any model type that supports animations. Add a "default" animation to it.
    2. Create a trimesh (which we'll convert into an animmesh only much later), and edit its shape as you see fit, keeping in mind this is going to be the starting and ending shape in the animation loop
    3. Create a second model base, that we'll use temporarily to store some data (this will be discarded and wont end up in game). Name it something memorable like "frames".
    4. Clone the trimesh and make sure you rename it by adding a semantic suffix to it (it'll make things easier later on). I use _frame001 etc.
    5. Move in place and link the cloned "frame" to your second modelbase. Apply any transforms, whether parametric of manual, face/vert/edge based, anything really. Do the same to the UV mapping if you want to animate the texture (any kind of transforms). This is going to be the first frame inbetween start and end.
    6. Please note: the only forbidden transforms are those that create new verts or tverts, or delete existing ones. So no slicing, cutting, tessellation, extrusion etc. No optimization, vert removal in poly mode, welding etc.
    7. Repeat step 5 as many times as necessary to have the desired number of frames (I usually clone the previous frame, so that it inherits the transforms from it and I can built on top of them). The pivot position of each cloned frame is irrelevant (it'll be discarded), feel free to move them around to make your viewport easy to work with.
    8. When all meshes/frames are done, add an aurora trimesh modifier on top (if you haven't yet), and reset/collapse them, in order to bake the transforms in.
    9. Export both models to ASCII format.

  • LaputianBirdLaputianBird Member Posts: 103
    Part 2, editing the ASCII and putting everything together:

    Now, if you use CleanModels3 by OldMansBeard, you don't need the last step, as the utility will perform it for you, beside checking the consistency and the formatting of the data.

    Otherwise, this is the last step you need to perform manually before testing your model in game:

  • Dark_AnsemDark_Ansem Member Posts: 910
    A spectacular result. This is in-game, yes?

  • LaputianBirdLaputianBird Member Posts: 103

    A spectacular result. This is in-game, yes?

    Yes - in game screenshot

  • TarotRedhandTarotRedhand Member Posts: 582
    Do you think you could make this tutorial into a downloadable pdf document? That way, even months or years later it would still be available. Most office software (including the free LibreOffice suite) let's you save documents in pdf format these days. Then post it somewhere like the vault.

    (Hint of course I think it's a great tutorial, I wouldn't be asking for a pdf version otherwise)


Sign In or Register to comment.