Ah, Brawl's vertex weights, the bane of anyone trying to fully learn
Brawl's model structure. The weights are actually in a couple
different places. In the header of the MDL0 file, I'm sure you will
see a long series of 0xFFFFFFFF, this is a quick way too find the
first listing.
Every joint in a model has a weight entry for itself, even if it isn't
actually used for weighting any vertices directly. In the MDL0's
header there will be a few 32 bit ints, followed by the aforementioned
block of 0xFFFFFFFF, and then a few more 32 bit ints. The first set
of ints are the indexes of the joints which have vertices that are
weighted only by them (a weight of 1.0 from that joint). After that
there will be a 0xFFFFFFFF entry for every weight used by them model
with influence from multiple joints, and finally the last set of ints
will be the indexes of joints which do not have have any vertices
weighted directly to them.
Next you will need to skip down a bit to the root entry titled
"NodeMix". This is the block of entries which start with either 0x03
or 0x05. I always forget which is which, so I may have it backwards,
but I believe that 0x05 is for weights which are only influenced by
one joint and the 0x03 is for weights with multiple joint influence.
The first set of weights (the ones weighted by a single joint) will
simply list the index of the weight (determined by where the weight
appeared up in the MDL0 header), followed by the index of the joint
which influences it. After that are the weights influenced by
multiple joints which will first have a 16 bit number for the number
of joint influences, followed by that number of entries with a 16 bit
index (the index of a weight which is influenced by only one joint
(not the index of the joint itself)), followed by a 32 bit float
telling the amount of influence that weight/joint has.
I should also mention that in each joint's header is the index of the
weight which it has full influence over. I don't think this is
actually ever used in game, but I figure I should mention it just in
case for the sake of completeness.
Next is the matter of how the weights are applied to the geometry.
There are two ways weights can be applied. The first id for a mesh
which is controlled entirely by a single joint, and the second is for
a mesh which will have different vertices weighted by different vertex
weights. For the first way, if the 8th byte of a polygon block is not
-1, then the entire mesh listed in that block will be weighted by the
weight with the index listed at 0x08. Also, the position of the mesh
will be multiplied to the inverse bind matrix of the joint that
controls it.
Second and finally, there is the matter of how they are applied when
the vertices in a mesh are controlled by multiple weights (0x08 ==
-1). I'm going to assume for this that you already have a basic
understanding of the Wii's primitive lists and draw functions (0x90
for a triangle, 0x98 for tristrip, etc.). In the list of primitive
draw commands there will be entries for transform matrices (0x20 for
position, 0x28 for normals, 0x30 for texture coords, and 0x38 for
lights (not really ever used)). Bear in mind I don't have my
computer, or any files for reference right now, so this may be
slightly off, but I'm sure that you could find any slight errors I
might make for this next part. I believe, after the flag byte (0x20
being the important one) there will be a 16 bit index of a weight,
followed by a 16 bit memory address which the Wii will use for finding
the transform matrix. You will need to find the index of this address
by doing a little math. I believe that for 0x20 the index is:
ActiveWeightIndex = (Address - 0xB000) / 0x1E
This index I will call the ActiveWeightIndex. After which will be a
series of draw commands with their vertex description. The first byte
will be the ActiveWeightIndex and the weight that controls it will be
the weight from the first index of that 0x20 entry. Also, if that
vertex's weight is controlled by a single joint (a weight of 1.0), then
you must multiply the position of that vertex by the inverse bind
matrix of the joint that controls it. Vertices that are weighted by
multiply joints do not have any transforms applied to them.
I hope this helps out a little and is at least somewhat
understandable. I tend to be pretty bad when explaining things like
this. If you need any clarification, feel free to ask. It is quite a
bit complicated and several people have asked me how it works, I
myself had to have it explained to me by Sabretooth, who is the real
genius here for being the one to actually figure it out. I also just
feel like mentioning that I'm playing around with the models in
Pokemon Battle Revolution, and the weights are giving me some trouble
there as well. Nintendo just can't make it easy for us.